2 回答

TA貢獻1900條經驗 獲得超5個贊
我認為不允許將類型用作鍵沒有任何好處。它只是一個可能會或可能不會使用的選項,類型不會因為您禁止將其用作映射鍵而變得更好或更小或更快。
但如果你想這樣做:規范:地圖類型:
比較運算符== 和 != 必須為鍵類型的操作數完全定義;因此鍵類型不能是函數、映射或切片。
因此,如果您可以違反比較運算符的條款,您就會隱含地得到您想要的。您有struct以下類型的 , 術語struct:
如果結構值的所有字段都是可比較的,則結構值是可比較的。如果它們對應的非空白字段相等,則兩個結構值相等。
所以struct值只有在它們的所有字段都是可比較的情況下才具有可比性(因此只能用作映射中的鍵)。只需添加一個類型不可比較的字段。
切片、映射和函數值不可比較。
因此,例如添加一個類型為切片的字段,您就完成了:
type MyType struct {
S string
i int
notComparable []int
}
嘗試將上述MyType內容用作密鑰:
m := map[MyType]int{}
你得到一個編譯時錯誤:
invalid map key type MyType
筆記:
我寫了關于禁止類型作為鍵沒有任何好處的文章。不僅如此:從現在開始,您將無法再對您的類型的值使用比較運算符(因為額外的、不可比較的字段),因此例如您失去了比較這些值的選項:
p1, p2 := MyType{}, MyType{}
fmt.Println(p1 == p2)
編譯時錯誤:
invalid operation: p1 == p2 (struct containing []int cannot be compared)
請注意,通過一個小技巧,您仍然可以保留您的類型的可比較性質,例如,通過不導出您的類型而是嵌入原始類型的包裝器類型;并將額外的、不可比較的類型添加到包裝器類型中,例如:
type myType struct {
S string
i int
}
type MyType struct {
myType
notComparable []int
}
func main() {
p1, p2 := MyType{}, MyType{}
fmt.Println(p1.myType == p2.myType)
}
這樣,您myType可以保持可比性,但仍會阻止導出的包裝器MyType類型用作鍵類型。

TA貢獻1843條經驗 獲得超7個贊
您的類型不應具有可比性,以免不適合作為映射鍵。
切片、映射和函數值不可比較
請參閱密鑰類型:
列表中明顯沒有切片、映射和函數。這些類型不能使用 比較==,也不能用作映射鍵。
所以如果你的類型是切片、映射或函數,你應該得到你需要的。
它可能是一個“別名”(定義一個新的命名類型):
type StringSliceWrap []string
type MyFunc func(i int)
該別名不會用作映射鍵。
2017 年更新:Brad Fitzpatrick 提供此提示(在您的 中添加一個切片struct)以確保您的類型struct不可比較:請參閱play.golang.org:
package main
// disallowEqual is an uncomparable type.
// If you place it first in your struct, you prevent == from
// working on your struct without growing its size. (Don't put it
// at the end; that grows the size of the struct)
type disallowEqual [0]func()
type T struct {
_ disallowEqual
Foo string
Bar int
}
func main() {
var t1 T
var t2 T
println(t1 == t2)
}
T 現在不能用作amp鍵!
- 2 回答
- 0 關注
- 172 瀏覽
添加回答
舉報