Go泛型:映射鍵的型別限制
問題:
為什麼以下內容使用通用鍊錶作為映射時程式碼無法編譯key?
type List[X any] interface { isList() } type Cons[X any] struct { Data X Next List[X] } func (Cons[X]) isList() {} func main() { x := Cons[int]{5, Nil[int]{}} m := map[List[int]]string{} m[x] = "Hi" fmt.Println(m[x]) fmt.Println(id(x)) }
答案:
在Go 1.18 和 1.19 中,映射鍵需要預先聲明的可比較約束,並且它將使用限制為嚴格可比較的類型支援 == 和 != 比較,而不會在運行時出現恐慌。介面即使支援相等比較,也不會實現可比較,因為它們具有無限類型集。
雖然 List[X] 介面本身可以用作映射鍵,但 Cons[X] 結構可以未實作可比較,因為它包含 List[X] 欄位。沒有更弱的約束可用於識別適合用作映射鍵的類型。
但是,在 Go 1.20(2023 年 2 月)中,此行為已修復。可比較現在接受根據語言規範可比較的所有類型,即使它們可能因比較而在運行時出現恐慌。這使得程式碼能夠成功編譯。
替代約束:
如果需要使用包含isList() 方法的約束,您可以定義自己的約束約束如下:
type List interface { comparable isList() bool }
然後,讓您的地圖鍵結構實作此List 接口,而不是聲明接口田野。
以上是為什麼通用鍊錶不能用作 Go 中的 Map Key(1.20 之前)?的詳細內容。更多資訊請關注PHP中文網其他相關文章!