我有一個可以用作地圖鍵的類型,但我想防止發生這種情況。我認爲,如果該類型包含私人成員,則其他程序包將無法使用,但無論如何,這似乎都有效。使該類型不能用作地圖鍵的最佳方式是什麼?如何防止將某個類型用作映射鍵?
type MyType struct {
A *A
b b
preventUseAsKey ?
}
我有一個可以用作地圖鍵的類型,但我想防止發生這種情況。我認爲,如果該類型包含私人成員,則其他程序包將無法使用,但無論如何,這似乎都有效。使該類型不能用作地圖鍵的最佳方式是什麼?如何防止將某個類型用作映射鍵?
type MyType struct {
A *A
b b
preventUseAsKey ?
}
我沒有看到禁止將某個類型用作關鍵字的好處。這只是一個選項,可能會或可能不會被使用,只是因爲您禁止將它用作地圖鍵,類型不會更好或更小或更快。
但是,如果你想這樣做:Spec: Map types:
The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.
所以,如果你違反了comparison operators的條款,你含蓄地得到你想要的。你必須爲struct
類型的一個struct
,條款:如果所有的領域是相當
Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non- blank fields are equal.
所以struct
值只可比的(因此只能在地圖中使用的密鑰)。 只需添加一個類型不可比的字段。
Slice, map, and function values are not comparable.
因此,例如,增加一個字段類型爲切片,就大功告成了:
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
類型。
比我的回答更完整,並且像往常一樣富有啓發性。 +1 – VonC
您的類型應not be comparable爲了不適合作爲地圖的關鍵。
Slice, map, and function values are not comparable
見Key Type:
Notably absent from the list are slices, maps, and functions; these types cannot be compared using
==
, and may not be used as map keys.
所以,如果你的類型片,映射或函數,你應該得到你所需要的。
這可能是一個「別名」(定義新named type):
type StringSliceWrap []string
type MyFunc func(i int)
該別名將不會被用來作爲地圖的關鍵。
更新2017年:Brad Fitzpatrick give this tip(在你的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
現在還不能用作放大器的關鍵!
我編輯了[我的答案](http://stackoverflow.com/a/37916798/6309):你實際上可以在你的結構中添加一種'preventUseAsKey'。 – VonC