我想編譯以下代碼。我從閱讀 Type Parameters Proposal (Go Generics) 中的理解是,這應該可行,但我一定遺漏了一些東西。
package main
import "fmt"
func main() {
s := Struct{A: "Hello World!"}
PrintA(s)
}
func PrintA[T Type](v T) {
fmt.Printf("%s\n", v.A)
}
type Type interface {
struct{ A string }
}
type Struct struct {
A string
}
func (s Struct) String() string {
return s.A
}
我得到的錯誤是:
./prog.go:7:8: 結構沒有實作型別(約束型別中的 struct{A string} 可能缺少 ~)./prog.go:11:23: vA 未定義(介面型別沒有方法 A)
我想T用特定型別的特定欄位表示所有結構。添加~沒有幫助。
這是已實施的提案中的一個示例,它是最新 Go beta 版本的一部分。
type structField interface {
struct { a int; x int } |
struct { b int; x float64 } |
struct { c int; x uint64 }
}
https://go.dev/play/p/KZh2swZuD2m?v=gotip
uj5u.com熱心網友回復:
是的,您是對的,它應該可以作業,并且提案中提到了它(約束中的復合型別):
對于復合型別 [...],只有當運算子接受相同的輸入型別(如果有)并為型別集中的所有型別產生相同的結果型別時,才可以使用操作。
(...這意味著,除其他外,在型別集中一起使用映射和切片會將映射型別限制為map[int]T,因為索引運算子 ( []) 輸入型別是int)
當所有欄位具有相同型別時的欄位訪問應該包含在這個定義中,但它有意識地被排除在 Go 1.18 實作之外。鏈接的 Go 問題#48522很好地闡述了期望(它應該有效)、Go 團隊的決定(他們認為此功能不是必需的)和解決方法(使用訪問器方法)。
解決方法歸結為我們一直在使用的舊的基于介面的多型性,沒有型別引數:
type Type interface {
GetA() string
}
func (s Struct) GetA() string {
return s.A
}
在這一點上,您甚至不必使用Type介面作為約束。它可以只是一個普通的介面型別:
func PrintA(v Type) {
fmt.Printf("%s\n", v.GetA())
}
部分相關,我問了一個類似的問題:如何將型別引數限制為嵌入另一個結構的結構?結論暫時與這里的結論基本一致。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/382078.html
