在Go中,只有当变量的类型为comparable时,它们才能使用==运算符进行比较或用作map的键。可比较的类型包括:
int,float64,...)string,rune)切片、map、函数 — 不可比较!
尝试比较这些值会导致编译错误。例如:
var a = []int{1,2,3} var b = []int{1,2,3} printf("%v", a==b) // 编译错误:切片只能与nil比较
要将值用作map的键,它必须是可比较的。如果类型不符合,即会出现编译错误。
“如果只有部分字段不可比较,两个结构体可以被认为是可比较的吗?”
许多人回答“可以”,但这是不正确的。如果结构体的至少一个字段不可比较(例如,这是一个切片或map),整个结构体就变得不可比较。
例子:
type T struct { A int S []string } var t1, t2 T t1 == t2 // 编译错误:切片不可比较
故事
开发人员尝试使用切片作为map的键来缓存计算结果,导致编译错误。将其替换为带有显式序列化器的字符串 — 问题解决了。
故事
在向用作字典键的结构中添加新字段(类型为切片)后,项目突然无法编译。原因:现在结构变得不可比较,但没有人预料到这会影响嵌套结构。
故事
为了基于包含切片的结构创建集合(set),尝试使用map。在没有了解比较规则的情况下,尝试比较元素时遇到许多运行时错误,但原因在于无法用这样的键进行编译。