[Go] "==" 与 reflect.DeepEqual
摘要
- 什么时候 
==不管用- 基础类型之间进行比较
 - 聚合类型之间进行比较
 
 - reflect.DeepEqual 介绍
 - reflect.DeepEqual 实践
- 针对基础类型的使用
 - 针对聚合类型的使用
 - 针对引用类型的使用
 - 特殊情况
 
 - 注
 - 总结
 
什么时候 “==” 不管用
要知道  == 什么时候不管用首先得知道其什么时候管用
基础类型之间进行比较
- 若比较的类型一致且均为基础类型,此时直接比较值的内容。
 - 若比较的类型不一致且均为基础类型,将会出现语法错误,编译失败。
 - 若比较的类型不一致,且存在一方为 inteface 类型包装基础类型
- 若 inteface 类型的实际类型与另一方的类型不一致,比较结束返回 false
 - 若 inteface 类型的实际类型与另一方的类型一致,比较实际值的内容。
 
 - 若比较的类型一致且均为 inteface 类型包装基础类型
- 若 inteface 类型的实际类型与另一方的实际类型不一致,比较结束返回 false
 - 若 inteface 类型的实际类型与另一方的实际类型一致,比较实际值的内容。
 
 
基础类型的比较比较简单就不上代码啦~
聚合类型之间进行比较
数组
- 若其内部元素为基础类型时且长度,类型,值均一致时,比较成功返回 true,否则为 false。
 - 若其内部元素为数组时参考上一条比较。
 - 若其内部元素为结构体时,参考下一条结构体的比较
 
结构体
- 当结构体内部存在 
map类型/slice类型/channel类型/函数类型 字段时,则该结构体不可使用==进行直接比较,否则语法错误,编译失败。 - 按照顺序比较两者结构体变量的成员变量,若满足所有比较则两者比较成功返回 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
未完待续
注
- 基础类型分为: 数字类型、字符串类型、布尔类型。
 - 聚合类型分为: 数组类型、结构体类型。
 - 引用类型: 指针类型、slice类型、map类型、函数类型、channel类型
 
参考:
- [The Laws of Reflection]: https://blog.golang.org/laws-of-reflection
 - [The Laws of Reflection] 翻译版: [Go 语言反射三定律] : https://segmentfault.com/a/1190000006190038
 - [Go语言中文网] : https://studygolang.com/
 - [Go 程序设计语言]