首頁 >後端開發 >Golang >為什麼通用鍊錶不能用作 Go 中的 Map Key(1.20 之前)?

為什麼通用鍊錶不能用作 Go 中的 Map Key(1.20 之前)?

Susan Sarandon
Susan Sarandon原創
2024-12-18 12:50:13952瀏覽

Why Can't Generic Linked Lists Be Used as Map Keys in Go (Prior to 1.20)?

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn