说我有值[root@localhost ml-100k]# ls -l /opt/hadoop/weekday_mapper.py
-rwxr--r--. 1 root root 278 Jun 17 10:10 /opt/hadoop/weekday_mapper.py
,a
和b
。我想知道他们是否平等。如果我做
c
然后我收到编译错误
if a == b == c{...}
这很明显,因为这解析为:
invalid operation: a == b == c (mismatched types bool and TypeOfABandC)
(a == b) == c
是一个布尔。
我当然能做到:
(a == b)
然而,这看起来并不好看,让人感到困惑。还有另一种方式吗?
答案 0 :(得分:17)
事先说明:
您最后提出的解决方案是最短,最清晰,最有效的方法来比较3个值是否相等:
if a == b && a == c {
fmt.Println("Clearest: all 3 are equal")
}
或者(根据自己的喜好):
if a == b && b == c {
fmt.Println("Clearest: all 3 are equal")
}
这个答案的其余部分(后面的内容)只是用语言规范和语言的能力来表达,展示我觉得有趣和有创意的东西。他们并不试图提供卓越的解决方案。
在Go Playground上尝试以下所有示例。这些示例建立在Spec: Comparison operators。
中定义的比较的术语和结果之上一般说明:在下面的示例中,我使用了interface{}
类型,它将适用于您的值所具有的任何类型(a
,b
和c
),但如果您使用例如,他们知道它们属于int
类型,您也可以使用该特定类型(这将提高效率并缩短示例的长度)。
map
作为一组if len(map[interface{}]int{a: 0, b: 0, c: 0}) == 1 {
fmt.Println("Map set: all 3 are equal")
}
有效地,我们将所有可比较的值放入map
作为键,如果全部相等,则地图中只有1对,因此地图的“长度”将为1.值类型地图在这里没有任何作用,它可以是任何东西。我使用了int
,因为这会产生最短的composite literal(定义{{1}}值)。
此解决方案非常灵活,因为您可以使用任意数量的值来测试所有值是否相等,而不仅仅是3。
阵列具有可比性(与切片不同):
map
如果if [2]interface{}{a, b} == [2]interface{}{b, c} {
fmt.Println("Arrays: all 3 are equal")
}
和true
(如果相应的元素相等),则数组比较结果为a == b
。
请注意,您也可以对任意数量的值应用此方法。对于5个值,它看起来像这样:
b == c
if [4]interface{}{a, b, c, d} == [4]interface{}{b, c, d, e} {
fmt.Println("Arrays: all 5 are equal")
}
map
此复合文字会将if map[interface{}]bool{a: b == c}[b] {
fmt.Println("Tricky map: all 3 are equal")
}
的比较结果指定给键b == c
。我们询问与密钥a
关联的值。如果b
,索引表达式的结果将是a == b
的结果,即是否所有3个值都相等。如果b == c
,那么值类型的零值将是结果,a != b
的情况为false
,正确地告知所有3个值都不相等。
bool
s struct
值也具有可比性,因此:
struct
if struct{ a, b interface{} }{a, b} == struct{ a, b interface{} }{b, c} {
fmt.Println("Anon structs: all 3 are equal")
}
s 如果我们事先定义一个简单的struct
:
struct
比较将更加紧凑:
type P struct{ a, b interface{} }
(注意if (P{a, b} == P{b, c}) {
fmt.Println("Structs: all 3 are equal")
}
语句的表达式必须放在括号中以避免parsing ambiguity - 否则它是编译时错误!)
切片无法比较,因此我们需要借用reflect.DeepEqual()
的一些帮助:
if
if reflect.DeepEqual([]interface{}{a, b}, []interface{}{b, c}) {
fmt.Println("Slices: all 3 are equal")
}
使用它:
func AllEquals(v ...interface{}) bool {
if len(v) > 1 {
a := v[0]
for _, s := range v {
if a != s {
return false
}
}
}
return true
}
此解决方案也很灵活,您可以使用任意数量的值调用if AllEquals(a, b, c) {
fmt.Println("Helper function: all 3 are equal")
}
。
请注意,如果我们还愿意在此处致电AllEquals()
,我们可以使AllEquals()
功能更加紧凑:
reflect.DeepEqual()