[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 程序设计语言]