泛型。即通過參數(shù)化類型來實現(xiàn)在同一份代碼上操作多種數(shù)據(jù)類型。泛型是在C#2.0引入的。泛型(Genericity)的字面意思是指具有在多種數(shù)據(jù)類型上皆可操作的含意,與模板有些相似。
成都創(chuàng)新互聯(lián)主營酒泉網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,app軟件開發(fā)公司,酒泉h5微信小程序定制開發(fā)搭建,酒泉網(wǎng)站營銷推廣歡迎酒泉等地區(qū)企業(yè)咨詢
泛型是程序設(shè)計語言的一種特性。允許程序員在強類型程序設(shè)計語言中編寫代碼時定義一些可變部分,那些部分在使用前必須作出指明。各種程序設(shè)計語言和其編譯器、運行環(huán)境對泛型的支持均不一樣。
優(yōu)點:
泛型方法可以出現(xiàn)在泛型或非泛型類型上。需要注意的是,并不是只要方法屬于泛型類型,或者甚至是方法的形參的類型是封閉類型的泛型參數(shù),就可以說方法是泛型方法。只有當方法具有它自己的類型參數(shù)列表時,才能稱其為泛型方法。在下面的代碼中,只有方法 G 是泛型方法。
泛型。即通過參數(shù)化類型來實現(xiàn)在同一份代碼上操作多種數(shù)據(jù)類型。泛型是在C#2.0引入的。泛型(Genericity)的字面意思是指具有在多種數(shù)據(jù)類型上皆可操作的含意,與模板有些相似。
優(yōu)點:
泛型類和泛型方法同時具備可重用性、類型安全和效率,這是非泛型類和非泛型方法無法具備的。泛型通常用與集合以及作用于集合的方法一起使用。
泛型是c#2.0的一個新增加的特性,它為使用c#語言編寫面向?qū)ο蟪绦蛟黾恿藰O大的效力和靈活性。不會強行對值類型進行裝箱和拆箱,或?qū)σ妙愋瓦M行向下強制類型轉(zhuǎn)換,所以性能得到提高。
擴展資料
泛型是程序設(shè)計語言的一種特性。允許程序員在強類型程序設(shè)計語言中編寫代碼時定義一些可變部分,那些部分在使用前必須作出指明。各種程序設(shè)計語言和其編譯器、運行環(huán)境對泛型的支持均不一樣。
參考資料泛型_百度百科
在本節(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 中的泛型。
泛型。即通過參數(shù)化類型來實現(xiàn)在同一份代碼上操作多種數(shù)據(jù)類型。泛型類和泛型方法同時具備可重用性、類型安全和效率,這是非泛型類和非泛型方法無法具備的。泛型通常用與集合以及作用于集合的方法一起使用。
泛型是c#2.0的一個新增加的特性,它為使用c#語言編寫面向?qū)ο蟪绦蛟黾恿藰O大的效力和靈活性。不會強行對值類型進行裝箱和拆箱,或?qū)σ妙愋瓦M行向下強制類型轉(zhuǎn)換,所以性能得到提高。
Java 的泛型
Java 泛型的參數(shù)只可以代表類,不能代表個別對象。由于Java泛型的類型參數(shù)之實際類型在編譯時會被消除,所以無法在運行時得知其類型參數(shù)的類型,而且無法直接使用基本值類型作為泛型類型參數(shù)。Java編譯程序在編譯泛型時會自動加入類型轉(zhuǎn)換的編碼,故運行速度不會因為使用泛型而加快。
由于運行時會消除泛型的對象實例類型信息等缺陷經(jīng)常被人詬病,Java及JVM的開發(fā)方面也嘗試解決這個問題,例如Java通過在生成字節(jié)碼時添加類型推導輔助信息,從而可以通過反射接口獲得部分泛型信息。通過改進泛型在JVM的實現(xiàn),使其支持基本值類型泛型和直接獲得泛型信息等。
Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成為現(xiàn)實。Go 團隊實施了一個看起來比較穩(wěn)定的設(shè)計草案,并且正以源到源翻譯器原型的形式獲得關(guān)注。本文講述的是泛型的最新設(shè)計,以及如何自己嘗試泛型。
例子
FIFO Stack
假設(shè)你要創(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{}。現(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的stop the world的時間有多么短,延遲有多么小,依然屬于這類語言,這就天然與c,cpp,rust間劃清了界線。雖然go初衷是成為系統(tǒng)級編程語言,雖然go的性能可以滿足99%的場合的需要,但不能否認的是在一些性能超級敏感的場合,選擇go依然要慎重。
go的另外一個“劣勢”就是能玩的花樣太少,崇尚一個事情只有一個或少數(shù)幾種寫法。這不符合某些開發(fā)人員炫技的心理需求。于是就被詬病為是資質(zhì)平平的程序員才會去用的語言。
go 1.18將加入泛型(類型參數(shù)),這算是