最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Go 1.17 泛型嘗鮮

2021-08-18 15:27 作者:渣理大大  | 我要投稿

今天,Go的1.17版本終于正式發(fā)布,除了帶來各種優(yōu)化和新功能外,1.17正式在程序中提供了嘗鮮的泛型支持,這一功能也是為1.18版本泛型正式實裝做鋪墊。意味著在6個月后,我們就可以正式使用泛型開發(fā)了。那在Go ?1.18正式實裝之前,我們在1.17版本中先嘗鮮一下泛型的支持吧。

泛型有什么作用?

在使用Go沒有泛型之前我們怎么實現(xiàn)針對多類型的邏輯實現(xiàn)的呢?有很多方法,比如說使用interface{}作為變量類型參數(shù),在內(nèi)部通過類型判斷進入對應(yīng)的處理邏輯;將類型轉(zhuǎn)化為特定表現(xiàn)的鴨子類型,通過接口定義的方法實現(xiàn)邏輯整合;還有人專門編寫了Go的函數(shù)代碼生成工具,通過批量生成不同類型的相同實現(xiàn)函數(shù)代替手工實現(xiàn)等等。這些方法多多少少存在一些問題:使用了interface{}作為參數(shù)意味著放棄了編譯時檢查,作為強類型語言的一個優(yōu)勢就被抹掉了。同樣,無論使用代碼生成還是手工書寫,一旦出現(xiàn)問題,意味著這些方法都需要重復(fù)生成或者進行批量修改,工作量反而變得更多了。

在Go中引入泛型會給程序開發(fā)帶來很多好處:通過泛型,可以針對多種類型編寫一次代碼,大大節(jié)省了編碼時間。你可以充分應(yīng)用編譯器的編譯檢查,保證程序變量類型的可靠性。借助泛型,你可以減少代碼的重復(fù)度,也不會出現(xiàn)一處出現(xiàn)問題需要修改多處地方的尷尬問題。這也讓很多測試工作變得更簡單,借助類型安全,你甚至可以少考慮很多的邊緣情況。

Go語言官方有詳細(xì)的泛型提案文檔可以在這里和這里查看詳情。

如何使用泛型

前面理論我們僅僅只做介紹,這次嘗鮮還是以實踐為主。讓我們先從一個小例子開始。

從簡單的例子開始

讓我們先從一個最簡單的例子開始:

這個函數(shù)可以實現(xiàn)任何需要使用+符號進行運算的類型,我們通過定義Addable類型,枚舉了所有可能可以使用add方法的所有的類型。比如我們在main函數(shù)中就使用了intstring兩種不同類型。

但是如果這時我們使用簡單的go run命令運行,會發(fā)現(xiàn)提示語法錯誤:

因為在Go 1.17中,泛型并未默認(rèn)開啟,你需要定義gcflags方式啟用泛型:

如果你覺得這種方式太過于復(fù)雜,每次都需要添加,也可以通過定義環(huán)境變量形式讓每次都帶此參數(shù)(不推薦,尤其是多版本環(huán)境時低版本Go中會報錯):

在Go中,泛型可以做什么更多更復(fù)雜的事情嗎?當(dāng)然可以。除了最基礎(chǔ)的算法實現(xiàn)以外,我們可以通過后面的幾個場景看一下泛型可用的場景。

實現(xiàn)類型安全的Map

在現(xiàn)實開發(fā)過程中,我們往往需要對slice中數(shù)據(jù)的每個值進行單獨的處理,比如說需要對其中數(shù)值轉(zhuǎn)換為平方值,在泛型中,我們可以抽取部分重復(fù)邏輯作為map函數(shù):

在這個例子中,我們定義了一個M類型,因此除了進行同樣類型的轉(zhuǎn)換外,也可以做不同類型的轉(zhuǎn)換:

實現(xiàn)類型安全的Map/Filter

除了操作數(shù)據(jù)以外,我們通常還需要對數(shù)據(jù)進行篩選。在前面的例子上,我們可以通過實現(xiàn)filterFunc實現(xiàn)更好的通用邏輯:


實現(xiàn)類型可靠的Worker Pool

除了上面這個例子,我們還可以通過泛型實現(xiàn)一個類型可靠的通用批量類型轉(zhuǎn)換函數(shù):


其他應(yīng)用

我們可以預(yù)見在Go 1.18版本中,多個標(biāo)準(zhǔn)庫會被新增或者擴展,包括:類型定義庫constraints,通用slice操作庫slices,通用類型安全mapmaps等等。因為這些會進入標(biāo)準(zhǔn)庫,大家可以先自行實現(xiàn)試用,真正線上使用建議等待標(biāo)準(zhǔn)庫添加內(nèi)容即可。

Go泛型的實現(xiàn)原理

我們回歸到最原始的例子快速看一下Go中是如何實現(xiàn)泛型的。為了方便分析,我們在所有func上添加go:noinline防止內(nèi)聯(lián),然后編譯程序進行分析。這里可能Go 1.17實現(xiàn)問題未能支持如go toolgo build -gcflags=all=-S之類的命令傳遞-G=3參數(shù),因此這里我們選擇第三方的反匯編工具看一下具體的實現(xiàn):

可以看到目前Go會根據(jù)類型將泛型展開成對應(yīng)類型函數(shù),這樣也會小小的增加編譯時間和編譯后文件大小。因為我測試使用Apple Silicon平臺,考慮大家可能不熟悉相關(guān)匯編,具體執(zhí)行邏輯不再具體展示。

其他注意事項

目前Go的泛型仍在開發(fā)過程中,即便在1.17beta到正式版過程中,很多泛型的corner ?case也正在完善過程中,比如在之前測試中我發(fā)現(xiàn)某些代碼在beta版本無法正確編譯,但是在RC中已可以正確編譯。目前的泛型實現(xiàn)未必代表1.18版本中是相同的實現(xiàn)細(xì)節(jié),甚至可能在1.18中提供更多的功能。同時,目前1.17泛型類型是無法在package中導(dǎo)出的,這導(dǎo)致在1.17版本中它的應(yīng)用場景大大的受限。如果你仍有計劃在某些場景中使用,我仍舊建議單元測試覆蓋你使用的場景情況,防止出現(xiàn)版本迭代可能導(dǎo)致的問題。


Go 1.17 泛型嘗鮮的評論 (共 條)

分享到微博請遵守國家法律
遂宁市| 旬邑县| 阳山县| 宜城市| 德化县| 大城县| 奉化市| 玛曲县| 青川县| 绥阳县| 绥芬河市| 阜南县| 灌阳县| 新宁县| 拉孜县| 泽州县| 北安市| 连云港市| 登封市| 神农架林区| 依兰县| 苏州市| 镇江市| 德惠市| 贵州省| 荆门市| 开阳县| 桑日县| 遵义市| 印江| 柯坪县| 砚山县| 皮山县| 华坪县| 汤阴县| 瑞安市| 梅河口市| 南雄市| 阜宁县| 静海县| 东至县|