go語言對泛型 go泛型為什么這么丑

go泛型的缺點

“劣勢”:go是帶垃圾回收的編程語言,因此不管go的stop the world的時間有多么短,延遲有多么小,依然屬于這類語言,這就天然與c,cpp,rust間劃清了界線。雖然go初衷是成為系統(tǒng)級編程語言,雖然go的性能可以滿足99%的場合的需要,但不能否認的是在一些性能超級敏感的場合,選擇go依然要慎重。

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、白云網(wǎng)站定制設計、自適應品牌網(wǎng)站建設、H5頁面制作商城網(wǎng)站建設、集團公司官網(wǎng)建設、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應式網(wǎng)頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為白云等各大城市提供網(wǎng)站開發(fā)制作服務。

go的另外一個“劣勢”就是能玩的花樣太少,崇尚一個事情只有一個或少數(shù)幾種寫法。這不符合某些開發(fā)人員炫技的心理需求。于是就被詬病為是資質(zhì)平平的程序員才會去用的語言。

go 1.18將加入泛型(類型參數(shù)),這算是

GO語言(十五):泛型入門(下)-

在本節(jié)中,您將添加通用函數(shù)調(diào)用的修改版本,進行小的更改以簡化調(diào)用代碼。您將刪除在這種情況下不需要的類型參數(shù)。

當 Go 編譯器可以推斷您要使用的類型時,您可以在調(diào)用代碼中省略類型參數(shù)。編譯器從函數(shù)參數(shù)的類型推斷類型參數(shù)。

請注意,這并不總是可能的。例如,如果您需要調(diào)用沒有參數(shù)的泛型函數(shù),則需要在函數(shù)調(diào)用中包含類型參數(shù)。

在 main.go 中,在您已有的代碼下方,粘貼以下代碼。

在此代碼中:

(1)調(diào)用泛型函數(shù),省略類型參數(shù)。

從包含 main.go 的目錄中的命令行,運行代碼。

接下來,您將通過將整數(shù)和浮點數(shù)的并集捕獲到您可以重用的類型約束(例如從其他代碼中)來進一步簡化函數(shù)。

正如您將在本節(jié)中看到的,約束接口也可以引用特定類型。

1、編寫代碼

在此代碼中:

b.在您已有的函數(shù)下方,粘貼以下通用 SumNumbers函數(shù)。

在此代碼中:

c.在 main.go 中,在您已有的代碼下方,粘貼以下代碼。

在此代碼中:

(1)調(diào)用SumNumbers打印每個map的總和。

與上一節(jié)一樣,在調(diào)用泛型函數(shù)時省略了類型參數(shù)(方括號中的類型名稱)。Go 編譯器可以從其他參數(shù)推斷類型參數(shù)。

從包含 main.go 的目錄中的命令行,運行代碼。

做得很好!您剛剛學習了 Go 中的泛型。

如何看待go語言泛型的最新設計?

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

例子

FIFO Stack

假設你要創(chuàng)建一個先進先出堆棧。沒有泛型,你可能會這樣實現(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)

}

但是,這里存在一個問題:每當你 Peek 項時,都必須使用類型斷言將其從 interface{} 轉(zhuǎn)換為你需要的類型。如果你的堆棧是 *MyObject 的堆棧,則意味著很多 s.Peek().(*MyObject)這樣的代碼。這不僅讓人眼花繚亂,而且還可能引發(fā)錯誤。比如忘記 * 怎么辦?或者如果您輸入錯誤的類型怎么辦?s.Push(MyObject{})` 可以順利編譯,而且你可能不會發(fā)現(xiàn)到自己的錯誤,直到它影響到你的整個服務為止。

通常,使用 interface{} 是相對危險的。使用更多受限制的類型總是更安全,因為可以在編譯時而不是運行時發(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)

}

這會向 Stack 添加一個類型參數(shù),從而完全不需要 interface{}?,F(xiàn)在,當你使用 Peek() 時,返回的值已經(jīng)是原始類型,并且沒有機會返回錯誤的值類型。這種方式更安全,更容易使用。(譯注:就是看起來更丑陋,^-^)

此外,泛型代碼通常更易于編譯器優(yōu)化,從而獲得更好的性能(以二進制大小為代價)。如果我們對上面的非泛型代碼和泛型代碼進行基準測試,我們可以看到區(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)存,同時泛型的速度是非泛型的兩倍。

合約(Contracts)

上面的堆棧示例適用于任何類型。但是,在許多情況下,你需要編寫僅適用于具有某些特征的類型的代碼。例如,你可能希望堆棧要求類型實現(xiàn) String() 函數(shù)

當前標題:go語言對泛型 go泛型為什么這么丑
路徑分享:http://muchs.cn/article30/ddcsipo.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供建站公司、移動網(wǎng)站建設、外貿(mào)建站、靜態(tài)網(wǎng)站網(wǎng)站策劃、面包屑導航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設