2022年3月15日,爭議非常大但同時也備受期待的泛型終于伴隨著Go1.18發(fā)布了。
平時對于版本更新都是漠不關心的,只是近幾個月關于泛型的討論呼聲越來越高,于是也來學習一下。
在開始之前,請先將你的Go升級到1.18及以上的版本
?
1.假設有一個求和的函數
我們先在當前目錄運行 go mod init 命令,為其提供新代碼的模塊路徑
go mod init test
go: creating new go.mod: module test
go: to add module requirements and sums:
go mod tidy
在當前目錄新建一個 main.go 文件
那么在早期的版本你可能會這樣寫
func Add(num map[string]int64) int64 {
var ret int64
for _, v := range num {
ret += v
}
return ret
}
在這段代碼中:
我們聲明了一個 map,從中循環(huán)取值累加并返回總和
那么調用的語句如下
func main() {
InitNum := map[string]int64{
"First": 10,
"Second": 20,
"Third":30,
}
fmt.Printf("Sum of all number is:%v",Add(InitNum))
}
在終端中輸入 go run main.go,運行代碼
$ go run main.go
Sum of all number is:60
2.如果我們想要對不同類型的參數求和呢?
你可能會想到:那我把參數的類型修改下,多搞幾個函數一一對應就好了
例如下面這樣:
func Add1(num map[string]int64) int64 {
var ret int64
for _, v := range num {
ret += v
}
return ret
}
?
func Add2(num map[string]float64) float64 {
var ret float64
for _, v := range num {
ret += v
}
return ret
}
但是這樣修改就有個問題:用起來太麻煩了,每想要一個新類型就要新生成一個對應類型的函數
泛型就能夠很好解決上述問題
3.添加泛型來處理多種類型
還是上面那個求和的案例,如果使用泛型,我們可以這么寫:
func SumIntOrFloat[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
- []中聲明了兩個類型參數 K 和 V,m 類型為 map[K]V。該函數返回一個類型為 V 的值。
- comparable 是 golang 新引入的預定義標識符,它允許任何類型的值可以用作比較運算符 == 和 !=
- int64 和 float64。使用 | 指定兩種類型的聯(lián)合,這意味著此約束允許任何一種類型。編譯器將允許任一類型作為調用代碼中的參數。
那么我們就可以很愉快的用不同類型的參數去調用這個求和函數
func main() {
IntNum := map[string]int64{
"First": 10,
"Second": 20,
"Third":30,
}
FloatNum := map[string]float64{
"First": 10,
"Second": 20,
"Third":30,
}
?
fmt.Printf("Sum of all int number is:%v \n", SumIntOrFloat(IntNum))
fmt.Printf("Sum of all float number is:%v ", SumIntOrFloat(FloatNum))
}
在終端中執(zhí)行,輸出結果為:
$ go run .
Sum of all int number is:60
Sum of all float number is:60