详解Go 语言中的比较操作符

2019-11-10 12:01:57刘景俊

比较接口类型的方法集不能相交。

接口类型 I 的 i 和 非接口类型 T 的 t 可比较,如果 T 实现了 I 则 T 类型的值是可比较的。如果 I 的 动态类型和 T 是相同的,并且 i 的动态值和 t 也是相同的,那么值是相等的:

type I interface {
  m()
}
type T struct{}
func (T) m() {}
type S struct{}
func (S) m() {}
func main() {
  t := T{}
  s := S{}
  var i I
  i = T{}
  fmt.Println(t == i) // true
  fmt.Println(s == i) // false
}
结构类型可比较,所以字段都需要比较。所有非空白字段相等则他们等。
a := struct {
  name string
  _ int32
}{name: "foo"}
b := struct {
  name string
  _ int32
}{name: "foo"}
fmt.Println(a == b) // true

Go 中 数组是同质的 —— 只有同一类型(数组元素类型)的值可以被存储其中。对于数组值比较,它们的元素类型需要可比较。如果对应的元素相同,数组就相等。

就是这样。上面列表很长但并不充满惊奇。尝试了解它在 JavaScript 是如何工作的……

有三种类型不能比较 —— maps, slices 和 functions。Go 编译器不允许这样做,并且编译比较 maps 的程序会引起一个错误 map can only be compared to nil. 。展示的错误告诉我们至少可以用 maps,slices 或 functions 和 nil 比较。

目前为止,我们知道接口值是可比较的,但 maps 是不可以的。如果接口值的动态类型是相同的,但是不能比较(如 maps),它会引起一个运行时错误:

type T struct {
  meta map[string]string
}
func (T) m() {}
func main() {
  var i1 I = T{}
  var i2 I = T{}
  fmt.Println(i1 == i2)
}
panic: runtime error: comparing uncomparable type main.T
goroutine 1 [running]:
panic(0x8f060, 0x4201a2030)
  /usr/local/go/src/runtime/panic.go:500 +0x1a1
main.main()
  ...

顺序操作符

这些操作符只能应用在三种类型:整数,浮点数和字符串类型。这没有什么特别的或 Go 特有的。值得注意的是字符串是按字典顺序排列的。byte-wise 一次一个字节并没有 Collation 算法。

fmt.Println("aaa" < "b") // true
fmt.Println("ł" > "z")  // true

结果

任何比较操作符的结果都是无类型布尔常量(true 或 false)。因为它没有类型,所以可以分配了给任何布尔变量:

var t T = true
t = 3.3 < 5
fmt.Println(t)

这段代码输出 true。另一个,尝试分配 bool 类型的值:

var t T = true
var b bool = true
t = b
fmt.Println(t)

产生一个错误,不能使用 b (bool类型)分配给 T 类型。

总结

以上所述是小编给大家介绍的Go 语言中的比较操作符,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对易采站长站网站的支持!