App下載

Golang 泛型

猿友 2022-08-12 15:41:11 瀏覽數(shù) (3047)
反饋
原文: https://mp.weixin.qq.com/s/1h_XxttT1EBQuu7PA9WnQw

2022年3月15日,爭(zhēng)議非常大但同時(shí)也備受期待的泛型終于伴隨著Go1.18發(fā)布了。

平時(shí)對(duì)于版本更新都是漠不關(guān)心的,只是近幾個(gè)月關(guān)于泛型的討論呼聲越來(lái)越高,于是也來(lái)學(xué)習(xí)一下。

在開始之前,請(qǐng)先將你的Go升級(jí)到1.18及以上的版本

?

1.假設(shè)有一個(gè)求和的函數(shù)

我們先在當(dāng)前目錄運(yùn)行 go mod init 命令,為其提供新代碼的模塊路徑

go mod init test 
go: creating new go.mod: module test
go: to add module requirements and sums:
        go mod tidy

在當(dāng)前目錄新建一個(gè) main.go 文件

那么在早期的版本你可能會(huì)這樣寫

func Add(num map[string]int64) int64 {
    var ret int64
    for _, v := range num {
        ret += v
    }
    return ret
}

在這段代碼中:

我們聲明了一個(gè) map,從中循環(huán)取值累加并返回總和

那么調(diào)用的語(yǔ)句如下

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,運(yùn)行代碼

$ go run main.go
Sum of all number is:60

2.如果我們想要對(duì)不同類型的參數(shù)求和呢?

你可能會(huì)想到:那我把參數(shù)的類型修改下,多搞幾個(gè)函數(shù)一一對(duì)應(yīng)就好了

例如下面這樣:

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
}

但是這樣修改就有個(gè)問(wèn)題:用起來(lái)太麻煩了,每想要一個(gè)新類型就要新生成一個(gè)對(duì)應(yīng)類型的函數(shù)

泛型就能夠很好解決上述問(wèn)題

3.添加泛型來(lái)處理多種類型

還是上面那個(gè)求和的案例,如果使用泛型,我們可以這么寫:

func SumIntOrFloat[K comparable, V int64 | float64](m map[K]V) V {
    var s V
    for _, v := range m {
        s += v
    }
    return s
}
  • []中聲明了兩個(gè)類型參數(shù) K 和 V,m 類型為 map[K]V。該函數(shù)返回一個(gè)類型為 V 的值。
  • comparable 是 golang 新引入的預(yù)定義標(biāo)識(shí)符,它允許任何類型的值可以用作比較運(yùn)算符 == 和 !=
  • int64 和 float64。使用 | 指定兩種類型的聯(lián)合,這意味著此約束允許任何一種類型。編譯器將允許任一類型作為調(diào)用代碼中的參數(shù)。

那么我們就可以很愉快的用不同類型的參數(shù)去調(diào)用這個(gè)求和函數(shù)

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í)行,輸出結(jié)果為:

$ go run .
Sum of all int number is:60 
Sum of all float number is:60


0 人點(diǎn)贊