[Go] "==" 与 reflect.DeepEqual

摘要

  1. 什么时候 == 不管用
    • 基础类型之间进行比较
    • 聚合类型之间进行比较
  2. reflect.DeepEqual 介绍
  3. reflect.DeepEqual 实践
    • 针对基础类型的使用
    • 针对聚合类型的使用
    • 针对引用类型的使用
    • 特殊情况
  4. 总结

什么时候 “==” 不管用

要知道 == 什么时候不管用首先得知道其什么时候管用

基础类型之间进行比较

  1. 若比较的类型一致且均为基础类型,此时直接比较值的内容。
  2. 若比较的类型不一致且均为基础类型,将会出现语法错误,编译失败。
  3. 若比较的类型不一致,且存在一方为 inteface 类型包装基础类型
    • 若 inteface 类型的实际类型与另一方的类型不一致,比较结束返回 false
    • 若 inteface 类型的实际类型与另一方的类型一致,比较实际值的内容。
  4. 若比较的类型一致且均为 inteface 类型包装基础类型
    • 若 inteface 类型的实际类型与另一方的实际类型不一致,比较结束返回 false
    • 若 inteface 类型的实际类型与另一方的实际类型一致,比较实际值的内容。

基础类型的比较比较简单就不上代码啦~

聚合类型之间进行比较

数组

  1. 若其内部元素为基础类型时且长度,类型,值均一致时,比较成功返回 true,否则为 false。
  2. 若其内部元素为数组时参考上一条比较。
  3. 若其内部元素为结构体时,参考下一条结构体的比较

结构体

  1. 当结构体内部存在 map 类型/slice 类型/channel 类型/函数类型 字段时,则该结构体不可使用 == 进行直接比较,否则语法错误,编译失败。
  2. 按照顺序比较两者结构体变量的成员变量,若满足所有比较则两者比较成功返回 true,否则返回 false。

more code less talk

第一种情况:

type Mapper struct {
    Map map[int]string
}
m1, m2 := Mapper{}, Mapper{}
// 编译失败 
// invalid operation: m1 == m2 (struct containing map[int]string cannot be compared)
fmt.Println(m1 == m2)

第二种情况:

type Point struct{ X, Y int }

p := Point{1, 2}
q := Point{2, 1}

// 以下两种比较无异
fmt.Println(p.X == q.X && p.Y == q.Y) // false
fmt.Println(p == q)                   // false

未完待续

  1. 基础类型分为: 数字类型、字符串类型、布尔类型。
  2. 聚合类型分为: 数组类型、结构体类型。
  3. 引用类型: 指针类型、slice类型、map类型、函数类型、channel类型

参考:


tangzixiang