學習 Go 泛型,我遇到了一個我似乎無法解開的錯誤。我把它歸結為最簡單的代碼:
type opStack[T any] []T
func main() {
t := make(opStack)
// t := new(opStack)
t = append(t, 0)
fmt.Println(t[0])
}
在操場上,這會在make()呼叫(以及類似地在被new注釋掉的呼叫)時出現以下錯誤訊息:
沒有實體化就不能使用泛型型別 opStack[T any]
但是make()是一個實體化函式。所以,我希望我錯過了一些語法上的微妙之處。Go 抱怨什么,需要更正什么?
uj5u.com熱心網友回復:
因為你想要
t = 附加(t,0)
資料型別可以是 int 或 float 組。
這段代碼應該可以作業
package main
import "fmt"
func main() {
type opStack[T any] []T
t := make(opStack[int], 0) // You must initialize data type here
t = append(t, 0)
fmt.Println(t[0])
}
uj5u.com熱心網友回復:
每當您使用引數化型別時,包括需要型別引數的任何地方,例如在 built-in 中make,您必須將其定義中的型別引數替換為實際型別。這稱為實體化。
t := make(opStack[int], 0)
t = append(t, 0)
如果將泛型型別用作另一個泛型型別的型別引數,也必須實體化泛型型別:
type Data[T any] struct {
data T
}
d := Data[opStack[int]]{ data: []int{0, 1, 2} }
語言規范中的相關參考(目前)在兩個不同的地方,型別定義:
如果型別定義指定型別引數,則型別名稱表示泛型型別。泛型型別在使用時必須實體化。
和實體化
泛型函式或型別通過用型別實參代替型別引數來實體化。[...]
在其他編程語言中,“實體化”可能是指創建物件的實體——在 Go 中,該術語專門指用具體型別替換型別引數。在我看來,該術語的用法仍然是一致的,盡管在 Go 中它并不一定意味著分配。
請注意,您可以呼叫沒有顯式型別引數的泛型函式。實體化也發生在那里,只是型別引數可能都是從函式引數中推斷出來的:
func Print[T, U any](v T, w U) { /* ... */ }
Print("foo", 4.5) // T is inferred from "foo", U from 4.5
推理也適用于泛型型別,但型別引數串列必須是非空的。因此,如果定義只有一種型別引數,您必須始終明確地提供它。
type Vector[T any] []T
// v := Vector[int]{} -> must supply T
type Matrix[T any, U ~[]T] []U
// m := Matrix[int]{} -> supply T, infers U from T
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/435083.html
