欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

學(xué)會(huì)提升Go語言編碼效率技巧拒絕加班!

 更新時(shí)間:2023年12月19日 10:58:11   作者:Go語言圈?磊豐  
這篇文章主要為大家介紹了Go語言編碼效率提升技巧詳解,學(xué)會(huì)了從此拒絕加班,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

在Go語言中,`slice`和`map`是我們常用的基礎(chǔ)類型,通過它們,我們可以輕松地處理數(shù)據(jù)。然而,你可能會(huì)注意到,為了處理這兩種數(shù)據(jù),我們不得不編寫許多實(shí)用函數(shù)。

比如,從`slice`切片中查找一個(gè)元素的位置。而這種查找又分為從前查找和從后查找。又或者,獲取`map`的所有鍵?或者所有的值?

再比如,在JavaScript中,數(shù)組的`map`、`reduce`、`filter`等函數(shù)非常好用,但是令人遺憾的是,Go標(biāo)準(zhǔn)庫沒有提供這樣的功能。

這些例子還有很多,而且都是我們?cè)诰幊讨薪?jīng)常需要的實(shí)用函數(shù)。但是,我們的Go SDK并沒有提供這些。

那么我們應(yīng)該怎么辦呢?

一種方法是自己編寫一個(gè)工具包,供項(xiàng)目使用,但是這個(gè)工具包的維護(hù)可能會(huì)成為一個(gè)問題,需要投入人力。

go-funk

第二種方式是使用開源庫,經(jīng)過充分的測(cè)試、驗(yàn)證,并且經(jīng)常更新,以確保可用性。

因?yàn)槲覀冇龅降氖浅R妴栴},所以一些人已經(jīng)做了開源庫,以供大家使用。

這樣的工具庫以Go 1.18為分界線,Go 1.18之前比較有名的是`go-funk`。

它有一個(gè)有趣的名字Repo

地址是 https://github.com/thoas/go-funk

它被官方介紹為一個(gè)現(xiàn)代化的Go實(shí)用工具庫:

"A modern Go utility library which provides helpers (map, find, contains, filter, ...)"

它提供了許多實(shí)用的函數(shù),比如`Contains`、`Difference`、`IndexOf`、`LastIndexOf`等等,具體更多的可以參考它的文檔。

然而,它有一個(gè)致命的問題,就是使用了反射。這也是無法避免的,因?yàn)樵贕o泛型沒有支持之前,只能通過反射來編寫滿足不同類型的函數(shù)。

舉個(gè)例子,如果不使用反射,要想支持更多的類型,就得定義很多相似名稱的函數(shù),如下所示:

func IndexOfBool(a []bool, x bool) int {
}
func IndexOfInt(a []int, x int) int {
}
func IndexOfInt32(a []int32, x int32) int {
}
func IndexOfInt64(a []int64, x int64) int {
}
func IndexOfUInt(a []uint, x uint) int {
}
func IndexOfUInt32(a []uint32, x uint32) int {
}
func IndexOfUInt64(a []uint64, x uint64) int {
}
func IndexOfFloat64(a []float64, x float64) int {
}
func IndexOfString(a []string, x string) int {
}

以上函數(shù)行不行?當(dāng)然行,但是會(huì)寫很多重復(fù)的代碼,并且看著也怪怪的。

在Go語言的泛型支持之前,要解決這個(gè)問題,只能通過反射。

在Go語言的泛型支持之前,處理slice和map的通用工具函數(shù)通常需要使用反射。

雖然這種方法可以幫助我們編寫更通用的代碼,但也會(huì)帶來一些性能開銷。

例如,考慮一個(gè)通用的查找函數(shù),用于在切片中查找特定的元素:

go
Copy code
import (
    "reflect"
)
func indexOf(slice interface{}, target interface{}) int {
    sliceValue := reflect.ValueOf(slice)
    for i := 0; i < sliceValue.Len(); i++ {
        element := sliceValue.Index(i).Interface()
        if element == target {
            return i
        }
    }
    return -1
}

上述函數(shù)使用了反射,它能夠接受任意類型的切片,并在其中查找目標(biāo)元素。然而,這種靈活性是以性能為代價(jià)的,因?yàn)榉瓷涞拈_銷相對(duì)較高。

在Go 1.18引入泛型之前,我們不得不在不同類型的切片和映射上編寫類似的通用函數(shù),這可能會(huì)導(dǎo)致很多重復(fù)的代碼。在實(shí)際應(yīng)用中,我們需要權(quán)衡代碼的通用性和性能開銷。

值得注意的是,Go語言的泛型支持已經(jīng)提供了更為優(yōu)雅和高效的解決方案,可以在不使用反射的情況下實(shí)現(xiàn)通用性。

使用泛型編寫更直觀且類型安全的通用函數(shù)

在Go 1.18及以后的版本中,你可以使用泛型編寫更直觀且類型安全的通用函數(shù)。

// IndexOf gets the index at which the first occurrence
// of value is found in array or return -1
// if the value cannot be found
func IndexOf(in interface{}, elem interface{}) int {
  inValue := reflect.ValueOf(in)
  elemValue := reflect.ValueOf(elem)
  inType := inValue.Type()
  if inType.Kind() == reflect.String {
    return strings.Index(inValue.String(), elemValue.String())
  }
  if inType.Kind() == reflect.Slice {
    equalTo := equal(elem)
    for i := 0; i < inValue.Len(); i++ {
      if equalTo(reflect.Value{}, inValue.Index(i)) {
        return i
      }
    }
  }
  return -1
}

泛型代碼復(fù)雜,并且效率低。。。

那么Go 1.18之后已經(jīng)支持了泛型,能不能用泛型來重寫呢?

答案是:當(dāng)然可以,并且已經(jīng)有人這么做了。這個(gè)庫就是 https://github.com/samber/lo

IndexOf函數(shù)實(shí)現(xiàn)

它是基于Go泛型實(shí)現(xiàn),沒有用到反射,效率高,代碼簡(jiǎn)潔。比如剛剛的IndexOf函數(shù),在該庫中是這么實(shí)現(xiàn)的:

// IndexOf returns the index at which the first occurrence of
// a value is found in an array or return -1
// if the value cannot be found.
func IndexOf[T comparable](collection []T, element T) int {
  for i, item := range collection {
    if item == element {
      return i
    }
  }

  return -1
}

只需要 T 被約束為comparable 的,就可以使用==符號(hào)進(jìn)行比較了,整體代碼非常簡(jiǎn)單,并且沒有反射。

IndexOf只是lo幾十個(gè)函數(shù)中的一個(gè),這些函數(shù)基本上覆蓋了slice、map、string等方方面面,涉及查找、比較大小、生成、map、reduce、過濾、填充、反轉(zhuǎn)、分組等等,使用方法和示例,可以參考go doc文檔

以上就是學(xué)會(huì)提升Go語言編碼效率技巧拒絕加班!的詳細(xì)內(nèi)容,更多關(guān)于Go語言編碼效率提升的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • VSCode Golang dlv調(diào)試數(shù)據(jù)截?cái)鄦栴}及處理方法

    VSCode Golang dlv調(diào)試數(shù)據(jù)截?cái)鄦栴}及處理方法

    這篇文章主要介紹了VSCode Golang dlv調(diào)試數(shù)據(jù)截?cái)鄦栴},本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Go實(shí)現(xiàn)并發(fā)緩存的示例代碼

    Go實(shí)現(xiàn)并發(fā)緩存的示例代碼

    高并發(fā)數(shù)據(jù)存儲(chǔ)是現(xiàn)代互聯(lián)網(wǎng)應(yīng)用開發(fā)中常遇到的一大挑戰(zhàn),本文主要介紹了Go實(shí)現(xiàn)并發(fā)緩存的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • Go?Gin框架優(yōu)雅重啟和停止實(shí)現(xiàn)方法示例

    Go?Gin框架優(yōu)雅重啟和停止實(shí)現(xiàn)方法示例

    Web應(yīng)用程序中,有時(shí)需要重啟或停止服務(wù)器,無論是因?yàn)楦麓a還是進(jìn)行例行維護(hù),這時(shí)需要保證應(yīng)用程序的可用性和數(shù)據(jù)的一致性,就需要優(yōu)雅地關(guān)閉和重啟應(yīng)用程序,即不丟失正在處理的請(qǐng)求和不拒絕新的請(qǐng)求,本文將詳解如何在Go語言中使用Gin這個(gè)框架實(shí)現(xiàn)優(yōu)雅的重啟停止
    2024-01-01
  • golang使用sort接口實(shí)現(xiàn)排序示例

    golang使用sort接口實(shí)現(xiàn)排序示例

    這篇文章主要介紹了golang使用sort接口實(shí)現(xiàn)排序的方法,簡(jiǎn)單分析了sort接口的功能并實(shí)例演示了基于sort接口的排序?qū)崿F(xiàn)方法,需要的朋友可以參考下
    2016-07-07
  • go for range遍歷二維數(shù)組的示例

    go for range遍歷二維數(shù)組的示例

    今天小編就為大家分享一篇關(guān)于go for range遍歷二維數(shù)組的示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • 詳解Golang中的各種時(shí)間操作

    詳解Golang中的各種時(shí)間操作

    這篇文章主要介紹了詳解Golang中的各種時(shí)間操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Golang 函數(shù)執(zhí)行時(shí)間統(tǒng)計(jì)裝飾器的一個(gè)實(shí)現(xiàn)詳解

    Golang 函數(shù)執(zhí)行時(shí)間統(tǒng)計(jì)裝飾器的一個(gè)實(shí)現(xiàn)詳解

    這篇文章主要介紹了Golang 函數(shù)執(zhí)行時(shí)間統(tǒng)計(jì)裝飾器的一個(gè)實(shí)現(xiàn)詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • 深入淺出Golang中的sync.Pool

    深入淺出Golang中的sync.Pool

    sync.Pool是可伸縮的,也是并發(fā)安全的,其大小僅受限于內(nèi)存大小。本文主要為大家介紹一下Golang中sync.Pool的原理與使用,感興趣的小伙伴可以了解一下
    2023-03-03
  • Go語言題解LeetCode1260二維網(wǎng)格遷移示例詳解

    Go語言題解LeetCode1260二維網(wǎng)格遷移示例詳解

    這篇文章主要為大家介紹了Go語言題解LeetCode1260二維網(wǎng)格遷移示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • golang抓取tcp包的實(shí)現(xiàn)方式

    golang抓取tcp包的實(shí)現(xiàn)方式

    使用`golang`的`packet`和`pcap`庫可以抓取TCP數(shù)據(jù)包,首先,確保安裝了`pcap`庫,然后使用以下代碼打開網(wǎng)絡(luò)接口,設(shè)置過濾規(guī)則為“tcp”,開始捕獲并解析TCP數(shù)據(jù)包,運(yùn)行代碼時(shí)需要管理員權(quán)限
    2024-12-12

最新評(píng)論