Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成為現(xiàn)實(shí)。Go 團(tuán)隊(duì)實(shí)施了一個(gè)看起來比較穩(wěn)定的設(shè)計(jì)草案,并且正以源到源翻譯器原型的形式獲得關(guān)注。本文講述的是泛型的最新設(shè)計(jì),以及如何自己嘗試泛型。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了承留免費(fèi)建站歡迎大家使用!
例子
FIFO Stack
假設(shè)你要?jiǎng)?chuàng)建一個(gè)先進(jìn)先出堆棧。沒有泛型,你可能會(huì)這樣實(shí)現(xiàn):
type?Stack?[]interface{}func?(s?Stack)?Peek()?interface{}?{
return?s[len(s)-1]
}
func?(s?*Stack)?Pop()?{
*s?=?(*s)[:
len(*s)-1]
}
func?(s?*Stack)?Push(value?interface{})?{
*s?=?
append(*s,?value)
}
但是,這里存在一個(gè)問題:每當(dāng)你 Peek 項(xiàng)時(shí),都必須使用類型斷言將其從 interface{} 轉(zhuǎn)換為你需要的類型。如果你的堆棧是 *MyObject 的堆棧,則意味著很多 s.Peek().(*MyObject)這樣的代碼。這不僅讓人眼花繚亂,而且還可能引發(fā)錯(cuò)誤。比如忘記 * 怎么辦?或者如果您輸入錯(cuò)誤的類型怎么辦?s.Push(MyObject{})` 可以順利編譯,而且你可能不會(huì)發(fā)現(xiàn)到自己的錯(cuò)誤,直到它影響到你的整個(gè)服務(wù)為止。
通常,使用 interface{} 是相對(duì)危險(xiǎn)的。使用更多受限制的類型總是更安全,因?yàn)榭梢栽诰幾g時(shí)而不是運(yùn)行時(shí)發(fā)現(xiàn)問題。
泛型通過允許類型具有類型參數(shù)來解決此問題:
type?Stack(type?T)?[]Tfunc?(s?Stack(T))?Peek()?T?{
return?s[len(s)-1]
}
func?(s?*Stack(T))?Pop()?{
*s?=?(*s)[:
len(*s)-1]
}
func?(s?*Stack(T))?Push(value?T)?{
*s?=?
append(*s,?value)
}
這會(huì)向 Stack 添加一個(gè)類型參數(shù),從而完全不需要 interface{}。現(xiàn)在,當(dāng)你使用 Peek() 時(shí),返回的值已經(jīng)是原始類型,并且沒有機(jī)會(huì)返回錯(cuò)誤的值類型。這種方式更安全,更容易使用。(譯注:就是看起來更丑陋,^-^)
此外,泛型代碼通常更易于編譯器優(yōu)化,從而獲得更好的性能(以二進(jìn)制大小為代價(jià))。如果我們對(duì)上面的非泛型代碼和泛型代碼進(jìn)行基準(zhǔn)測(cè)試,我們可以看到區(qū)別:
type?MyObject?struct?{
X?
int
}
var?sink?MyObjectfunc?BenchmarkGo1(b?*testing.B)?{
for?i?:=?0;?i??b.N;?i++?{
var?s?Stack
s.Push(MyObject{})
s.Push(MyObject{})
s.Pop()
sink?=?s.Peek().(MyObject)
}
}
func?BenchmarkGo2(b?*testing.B)?{
for?i?:=?0;?i??b.N;?i++?{
var?s?Stack(MyObject)
s.Push(MyObject{})
s.Push(MyObject{})
s.Pop()
sink?=?s.Peek()
}
}
結(jié)果:
BenchmarkGo1BenchmarkGo1-16?????12837528?????????87.0?ns/op???????48?B/op????????2?allocs/opBenchmarkGo2BenchmarkGo2-16?????28406479?????????41.9?ns/op???????24?B/op????????2?allocs/op
在這種情況下,我們分配更少的內(nèi)存,同時(shí)泛型的速度是非泛型的兩倍。
合約(Contracts)
上面的堆棧示例適用于任何類型。但是,在許多情況下,你需要編寫僅適用于具有某些特征的類型的代碼。例如,你可能希望堆棧要求類型實(shí)現(xiàn) String() 函數(shù)
最近在做一個(gè)內(nèi)網(wǎng)穿透工具,是用C# Dotnet Core寫的。 總擔(dān)心性能不行,想?yún)⒖枷聞e人寫的。 結(jié)果搜到很多GO語言的例子。 看了下Go語言的介紹,覺得確實(shí)是比較簡(jiǎn)單的語言。并且在并發(fā)上比較方便。于是,就開始學(xué)習(xí)Go語言,并用Go把內(nèi)網(wǎng)穿透工具重新寫了一下。
然后,又想用Go語言重寫之前的DotnetCore的WebAPI,現(xiàn)在還在編寫中,只是對(duì)比下兩個(gè)語言差異。
然后看下 C#
實(shí)際上目前我也沒有能力判斷GO和C#哪個(gè)更好
2021-11-10
列表是一種非連續(xù)的存儲(chǔ)容器,有多個(gè)節(jié)點(diǎn)組成,節(jié)點(diǎn)通過一些變量記錄彼此之間的關(guān)系
單鏈表和雙鏈表就是列表的兩種方法。
原理:A、B、C三個(gè)人,B懂A的電話,C懂B的電話只是單方知道號(hào)碼,這樣就形成了一個(gè)單鏈表結(jié)構(gòu)。
如果C把自己的號(hào)碼給B,B把自己的號(hào)碼給A,因?yàn)槭请p方都知道對(duì)方的號(hào)碼,這樣就形成了一個(gè)雙鏈表結(jié)構(gòu)
如果B換號(hào)碼了,他需要通知AC,把自己的號(hào)碼刪了,這個(gè)過程就是列表的刪除操作。
在Go語言中,列表使用 container/list 包來實(shí)現(xiàn),內(nèi)部的實(shí)現(xiàn)原理是雙鏈表,列表能夠高效地進(jìn)行任意位置的元素插入和刪除操作。
列表初始化的兩種辦法
列表沒有給出具體的元素類型的限制,所以列表的元素可以是任意類型的,
例如給列表中放入了一個(gè) interface{} 類型的值,取出值后,如果要將 interface{} 轉(zhuǎn)換為其他類型將會(huì)發(fā)生宕機(jī)。
雙鏈表支持從隊(duì)列前方或后方插入元素,分別對(duì)應(yīng)的方法是 PushFront 和 PushBack。
列表插入函數(shù)的返回值會(huì)提供一個(gè) *list.Element 結(jié)構(gòu),這個(gè)結(jié)構(gòu)記錄著列表元素的值以及與其他節(jié)點(diǎn)之間的關(guān)系等信息,從列表中刪除元素時(shí),需要用到這個(gè)結(jié)構(gòu)進(jìn)行快速刪除。
遍歷完也能看到最后的結(jié)果
學(xué)習(xí)地址:
就目前來看還是很有前景,因?yàn)樵絹碓交鹆耍贿^他的應(yīng)用領(lǐng)域還是局限在高并發(fā)處理和網(wǎng)站開發(fā),畢竟是后起之秀所以在其他桌面程序領(lǐng)域沒那么容易普及和超越c++,找工作就不推薦學(xué)go
? 隨著 2022 年 3 月 15 日 go 1.18 正式發(fā)布,新版本除了對(duì)性能的提升之外,還引入了很多新功能,其中就有 go 期盼已久的功能泛型(Generics),同時(shí)還引入的多模塊工作區(qū)(Workspaces)和模糊測(cè)試(Fuzzing)。
? 關(guān)于泛型網(wǎng)上已經(jīng)有很多介紹的教程了,這里我介紹一個(gè)實(shí)用的功能,多模塊工作區(qū)的使用方法和教程。
? Go 多模塊工作區(qū)能夠使開發(fā)者能夠更容易地同時(shí)處理多個(gè)模塊的工作,如:
? 多模塊工作區(qū)
? 開發(fā)流程演示
? 總結(jié)
? 參考文獻(xiàn)
? go 使用的是多模塊工作區(qū),可以讓開發(fā)者更容易同時(shí)處理多個(gè)模塊的開發(fā)。在 Go 1.17 之前,只能使用 go.mod replace 指令來實(shí)現(xiàn),如果你正巧是同時(shí)進(jìn)行多個(gè)模塊的開發(fā),使用它可能是很痛苦的。每次當(dāng)你想要提交代碼的時(shí)候,都不得不刪除掉 go.mod 中的 replace 才能使模塊穩(wěn)定的發(fā)布版本。 ?在使用 go 1.18 多模塊工作區(qū)功能的時(shí)候,就使用這項(xiàng)工作變得簡(jiǎn)單容易處理。下面我來介紹怎么使用這一功能。? Go 多模塊工作區(qū)文檔、代碼示例[5]
? 首先 我們需要 go 1.18 或更高版本 go 安裝[6]
? 通常情況下,建議不要提交 go.work 文件到 git 上,因?yàn)樗饕糜诒镜卮a開發(fā)。
? 推薦在: $GOPATH 路徑下執(zhí)行,生成 go.work 文件
? go work init 初始化工作區(qū)文件,用于生成 go.work 工作區(qū)文件
? go work use 添加新的模塊到工作區(qū)
? go work edit 用于編輯 go.work 文件
? go work sync 將工作區(qū)的構(gòu)建列表同步到工作區(qū)的模塊
? go env GOWORK
? 文件結(jié)構(gòu)和 go.mod 文件結(jié)構(gòu)類似,支持 Go 版本號(hào)、指定工作區(qū)和需要替換的倉庫 ?文件結(jié)構(gòu)示例:
? 可以使用 go work use hello 添加模塊,也可以手動(dòng)修改 go.work 工作區(qū)添加新的模塊 ?在工作區(qū)中添加了模塊路徑,編譯的時(shí)候會(huì)自動(dòng)使用 use 中的本地代碼進(jìn)行代碼編譯,和 replaces 功能類似。
? replaces 命令與 go.mod 指令相同,用于替換項(xiàng)目中依賴的倉庫地址 ?需要注意的是 replaces 和 use 不能同時(shí)指定相同的本地路徑
? 錯(cuò)誤示例
? 在同時(shí)使用 go.work 和 go.mod replace 功能的的時(shí)候分別指定不同的代碼倉庫路徑, go.work 優(yōu)先級(jí)高于 go.mod 中定義
? 在代碼構(gòu)建時(shí)候使用的是 go.work 指定的 example1 倉庫的代碼, go.work 優(yōu)先級(jí)別更高
? 在 Go 1.18 go run 和 go build 都會(huì)默認(rèn)使用工作區(qū)功能 ? GOWORK 也可以指定配置 go.work 文件位置
? Go 全局變量 GOWORK 設(shè)置 off 則可以禁用工作區(qū)功能
? 演示如何使用多模塊工作區(qū)功能。在現(xiàn)在微服務(wù)盛行的年代,一個(gè)人會(huì)維護(hù)多個(gè)代碼倉庫,很多的時(shí)候是多個(gè)倉庫進(jìn)行同時(shí)開發(fā)
? 假設(shè)我們現(xiàn)在進(jìn)行 hello 倉庫開發(fā),實(shí)現(xiàn)的功能是,實(shí)現(xiàn)將輸入的字符串反轉(zhuǎn)并輸出,字符串反轉(zhuǎn)功能依賴于 github.com/link1st/example (下文統(tǒng)稱 example )公共倉庫實(shí)現(xiàn)
? 新建 hello 項(xiàng)目
? main.go 代碼
? 運(yùn)行代碼 go run main.go -str "hello world" 或 go run github.com/link1st/link1st/workspaces/hello -str "hello world" 可以看到輸出了 hello world 反轉(zhuǎn)以后的字符串
? 到這里,最初的功能已經(jīng)完成,但是后續(xù)需求變動(dòng),不僅需要輸出反轉(zhuǎn)以后的字符串,還需要將字符串大寫
? 我們則需要去 example 倉庫中添加開發(fā) 將字符串大寫的功能
? vim example/stringutil/to_upper.go 代碼如下
? 由于代碼還在本地調(diào)試,未提交 git 倉庫中,這個(gè)時(shí)候就需要用到 Go 多模塊工作區(qū)的功能了。
? 進(jìn)入項(xiàng)目根目錄,初始化我們現(xiàn)在正在開發(fā)的模塊
? 文件結(jié)構(gòu)如下
? 回到 hello 項(xiàng)目, vim main.go 將字符串大寫的功能添加上。
? 運(yùn)行代碼
? 到這里,演示的代碼已經(jīng)全部完成
? 使用 Go 多模塊工作區(qū)的功能,可以讓我們輕松在多個(gè)模塊之間切換工作,更能適應(yīng)現(xiàn)代微服務(wù)架構(gòu)開發(fā)。
[1] Go 1.18 新特性多模塊工作區(qū)教程:
[2] Go 1.18 is released!:
[3] Tutorial: Getting started with multi-module workspaces:
[4] go-1.18-features:
網(wǎng)站欄目:2021go語言新特性,2021csgo設(shè)置
標(biāo)題URL:http://chinadenli.net/article30/hshdso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、營銷型網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、小程序開發(fā)、、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)