如何防止类型被用作映射键?

我有一种可以用作映射键的类型,但我想防止这种情况发生。我假设如果该类型包含一个私有成员,那么其他包就不可能,但这似乎仍然有效。使该类型无法用作映射键的最佳方法是什么?


type MyType struct {

    A *A

    b b


    preventUseAsKey ?

}


慕神8447489
浏览 152回答 2
2回答

梵蒂冈之花

我认为不允许将类型用作键没有任何好处。它只是一个可能会或可能不会使用的选项,类型不会因为您禁止将其用作映射键而变得更好或更小或更快。但如果你想这样做:规范:地图类型:比较运算符== 和 != 必须为键类型的操作数完全定义;因此键类型不能是函数、映射或切片。因此,如果您可以违反比较运算符的条款,您就会隐含地得到您想要的。您有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类型用作键类型。

蓝山帝景

您的类型不应具有可比性,以免不适合作为映射键。切片、映射和函数值不可比较请参阅密钥类型:列表中明显没有切片、映射和函数。这些类型不能使用 比较==,也不能用作映射键。所以如果你的类型是切片、映射或函数,你应该得到你需要的。它可能是一个“别名”(定义一个新的命名类型):type StringSliceWrap []stringtype 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键!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go