在 2022-03-22 這天 Go 正式發佈 1.18 版了! 這個版本其中一大特色就是增加了社群討論許久的泛型(Generics)

今天來玩看看 go 的泛型函數(Generics Function)

沒有泛型

我們來寫一個尋找 slice 資料索引的 function

在沒有使用泛型的情況下,處理一種類別就要寫一個 function

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
func FindIndexInt(x []int, y int) (int, error) {
	for k := range x {
		if y == x[k] {
			return k, nil
		}
	}
	return -1, errors.New("Not found")
}

func FindIndexString(x []string, y string) (int, error) {
	for k := range x {
		if y == x[k] {
			return k, nil
		}
	}
	return -1, errors.New("Not found")
}

依照類別的不同,自己選擇對應的 function

1
2
3
4
5
6
7
8
fmt.Println("FindIndexInt()")
fmt.Println(FindIndexInt([]int{9, 8, 7, 6, 5}, 9))
fmt.Println(FindIndexInt([]int{9, 8, 7, 6, 5}, 6))
fmt.Println(FindIndexInt([]int{9, 8, 7, 6, 5}, 10))

fmt.Println("FindIndexString()")
fmt.Println(FindIndexString([]string{"x", "y", "z"}, "z"))
fmt.Println(FindIndexString([]string{"x", "y", "z"}, "a"))

輸出結果

1
2
3
4
5
6
7
8
FindIndexInt()
0 <nil>
3 <nil>
-1 Not found

FindIndexString()
2 <nil>
-1 Not found

使用泛型

使用泛型讓 function 可以一次支援多種的類別,我們需要在宣告 function 時,增加類別參數(type parameters)。此外,因為會使用到 == 比對資料,所以要把類別限制為 comparable

comparable 是 1.18 新增的類別,專門用在泛型的類別約束(type constraint),代表所有可以使用 ==!= 做比較的類別

將程式改寫如下:

1
2
3
4
5
6
7
8
func FindIndex[T comparable](x []T, y T) (int, error) {
	for k := range x {
		if y == x[k] {
			return k, nil
		}
	}
	return -1, errors.New("Not found")
}

將不同類別的資料代入 function

1
2
3
4
5
6
7
8
fmt.Println("FindIndex[T comparable]() with int slice")
fmt.Println(FindIndex([]int{9, 8, 7, 6, 5}, 9))
fmt.Println(FindIndex([]int{9, 8, 7, 6, 5}, 6))
fmt.Println(FindIndex([]int{9, 8, 7, 6, 5}, 10))

fmt.Println("FindIndex[T comparable]() with string slice")
fmt.Println(FindIndex([]string{"x", "y", "z"}, "z"))
fmt.Println(FindIndex([]string{"x", "y", "z"}, "a"))

我們會拿到一樣的結果

1
2
3
4
5
6
7
8
FindIndex[T comparable]() with int slice
0 <nil>
3 <nil>
-1 Not found

FindIndex[T comparable]() with string slice
2 <nil>
-1 Not found

總結

這是一個泛型的小試身手,翻了翻目前官方提供的教學中,function 的應用應該是最簡單好懂的。其他泛型的應用有一點眼花撩亂,等我看懂了再繼續寫。

Reference