首頁 > 後端開發 > Golang > Go 泛型對映射鍵的「可比較」約束可以放寬嗎?

Go 泛型對映射鍵的「可比較」約束可以放寬嗎?

Susan Sarandon
發布: 2024-12-18 12:38:22
原創
666 人瀏覽過

Can Go Generics' `comparable` Constraint Be Relaxed for Map Keys?

Go 泛型:映射鍵的型別限制?

在 Go 1.18 及更早版本中,用作映射鍵的類型需要預先聲明的可比較約束。此約束可確保類型支援 == 和 != 運算符,並且在使用這些運算符時不會出現恐慌。

但是,此約束並不總是適合可用作映射鍵的類型。例如,以下程式碼定義了一個通用鍊錶:

type List[X any] interface {
    isList()
}

type Cons[X any] struct {
    Data X
    Next List[X]
}

func (Cons[X]) isList() {}

type Nil[X any] struct{}

func (Nil[X]) isList() {}
登入後複製

此程式碼定義了一個 List 接口,該介面由兩種類型實作:Cons 和 Nil。 Cons 類型表示非空列表,而 Nil 類型表示空列表。

以下程式碼使用 List 介面建立清單到字串的對應:

type List[X any] interface {
    isList()
}

func main() {
    x := Cons[int]{5, Nil[int]{}}
    m := map[List[int]]string{}
    m[x] = "Hi"        // succeeds
    fmt.Println(m[x])  // prints "Hi"
}
登入後複製

這段程式碼將成功編譯並執行。但是,如果我們嘗試在 Cons 類型上使用方法,則會收到編譯器錯誤:

type List[X any] interface {
    isList()
}

func main() {
    x := Cons[int]{5, Nil[int]{}}
    fmt.Println(id(x)) // error: Cons[int] does not implement comparable
}
登入後複製

錯誤訊息表示 Cons[int] 類型沒有實作可比較約束。這是因為 Cons 類型有一個 List[int] 類型的字段,而 List[int] 介面沒有實現可比較的約束。

解決此問題的一個可能的解決方案是使用較弱的類型限制。例如,我們可以使用以下約束:

type List[X any] interface {
    isList()
    Comparable() bool
}
登入後複製

此約束允許我們使用 Cons 類型作為映射鍵,即使它沒有實現類似的約束。

Go 1.20(2023 年 2 月)

可比較約束是映射鍵的正確包羅萬象的約束。根據 Go 規範可比較的所有類型,即使比較可能在運行時發生恐慌,也可以滿足可比較約束。您的程式碼將在 1.20 中按預期進行編譯。

這最終修復了先前的 Go 版本中關於規範可比較類型與可比較類型的不一致問題。

以上是Go 泛型對映射鍵的「可比較」約束可以放寬嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板