Go比较运算符==是万能的吗

156 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 11天,点击查看活动详情

前言

Go语言是没有隐式类型转换的,要对两个变量进行对比,那么类型必须先保持一致,然后才能做对比。

比较运算符==是万能的吗?所有的类型是否都能用这个==进行对比呢?

先说结论

答案,显然是否定的

按是否能做对比,将类型做个分类:

  • 不可对比类型:slice、map、func;
  • 可对比类型:基本数据类型(整型、浮点型、布尔型、字符串型)、指针、结构体、数组、接口、通道;

补充说明:

  1. 不可对比类型,做对比时,会编译失败,但有个例外,它们都可以和nil做对比;
  2. 可对比类型,并不是所有情况都可以对比,如果包含不可对比类型,也会导致编译失败;

指针

指针:可比较。如果两个指针指向相同的地址或者两者都为nil,则相等;除此之外,都不相等

func pointerCompare() {
  var p1 *int
  p1 = new(int)
  var p2 *int
  p2 = new(int)
  p3 := p1

  fmt.Println(p1 == p2) //false:指向不同地址,所以不相等
  fmt.Println(p1 == p3) //true:指向相同地址,所以相等

  var p4 *int
  var p5 *int
  fmt.Println(p4 == p5) //true:都为nil,所以相等
  fmt.Println(p4 == p1) //false:一个为nil,一个有指向的地址,所以不相等
}

结构体

结构体:可比较,但前提是所有字段都得可对比,如果包含不可对比字段(例如slice类型的字段),则会编译失败
两个结构体的所有字段都是可比较的,相等是指: 字段类型、字段个数、字段顺序、字段值完全一致。

type Student struct {
  Name string
  Age  int
  //Score []int
}

func structCompare() {
  s1 := Student{
    Name: "张三",
    Age:  18,
  }
  s2 := Student{
    Name: "张三",
    Age:  18,
  }
  s3 := Student{
    Name: "李四",
    Age:  18,
  }

  fmt.Println(s1 == s2) //true:字段值都相等,所以相等
  //fmt.Println(s1 == s2) //包含Score字段时,编译失败 invalid operation: s1 == s2 (struct containing []int cannot be compared)
  fmt.Println(s1 == s3) //false

  s4 := Student{}
  s5 := Student{}
  fmt.Println(s4 == s5) //true:默认各字段都是零值,也是相等的
}

数组

数组:可比较,但前提是数组长度一致,同时包含的元素都得可对比。递归对比所有元素,都相等则相等

func arrayCompare() {
  a1 := [4]int{1, 2, 3}
  a2 := [4]int{1, 2, 3}
  fmt.Println(a1 == a2) //true:元素都相等
  a3 := [4]int{1, 2}
  fmt.Println(a1 == a3) //false:元素有不相等的

  a4 := [1]Student{
    {Name: "李四", Age: 18},
  }
  a5 := [1]Student{
    {Name: "张三", Age: 18},
  }
  fmt.Println(a4 == a5) //false:元素有不相等的
}

如果本文对你有帮助,欢迎点赞收藏加关注,如果本文有错误的地方,欢迎指出!