自 Go 1.18 支援泛型也一段時間了,在此紀錄一下泛型的使用
基本用法
使用 []
來定義泛型型別(Generic Type Parameters)。
例如以下程式碼, N
可以是 int、float32、float64
func foo[N int | float32 | float64](a, b N) {
fmt.Printf("%v + %v = %v", a, b, a+b)
}
所以 foo(1.1, 2.1)
或是 foo(1, 2)
都可以正常執行。
定義泛型型別
以以上程式碼為例,可以改寫成
type IntOrFloat interface {
int | float32 | float64
}
func foo[N IntOrFloat](a, b N) {
fmt.Printf("%v + %v = %v", a, b, a+b)
}
事前先定義泛型型別 IntOrFloat
,事後其他 func
也能使用該泛型型別。
struct 內的泛型型別
要定義一個使用到泛型的 struct ,可以這樣寫
type foo[N comparable] struct {
data N
}
要作為 func 參數的話:
func bar[N comparable](f foo[N]) {}
組合 struct
如果要組合的話,則:
type foo2[N comparable] struct {
foo[N]
}
Struct Function
在 Struct 裡面的 function 是不能另外使用泛型的。
說得更好懂一點,在 Java 裡面,可以這樣使用泛型:
class Foo{
public <T> void bar (T t){
// ...
}
}
但 go 就不能,即以下 code 是不行的:
type Foo struct{}
func (f *Foo) Bar[N comparable](n N) {}
Struct 裡面的 function 只能使用預先定義好的泛型,例如
type Foo [N comparable]struct{}
func (f *Foo) Bar(n N) {}
官方說明中有解釋原由。
type func 內的泛型型別
要定義一個使用到泛型的 func type ,可以這樣寫
type foo[N comparable] func(n N)
將func foo
作為參數的話,則
func bar[N comparable](f foo[N]) {
// do something...
}
這樣的話,要執行 bar 會如下::
bar(func(i int){})
bar(func(i int64){})
bar(func(s string){})
Interface Function
Interface 和 Struct 的 function 其實差不多:泛型必須定義在 Interface 上,而不能直接定義在 interface 的 function。
即得這樣寫
type Foo interface[N comparable]{
Bar(n N)
}
不能這樣寫
type Foo interface{
Bar[N comparable](n N)
}
沒有留言:
張貼留言