golang 的结构体也就是 struct 能否比较呢?
直接说结论,是要分情况的,也就是要看 struct 中究竟存储的数据类型。
case 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| type Value struct { Name string Age int }
func main() { v1 := Value{Name: "viola", Age: 3} v2 := Value{Name: "viola", Age: 3} if v1 == v2 { fmt.Println("居然相等哎") return }
fmt.Println("居然不相等哎") }
|
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 居然相等哎 ```
#### case 2 改一下上面的例子,增加指针类型的引用 ```go type Value struct { Name *string Age int } func main() { v1 := Value{Name: new(string), Age: 3} v2 := Value{Name: new(string), Age: 3} if v1 == v2 { fmt.Println("居然相等哎") return } fmt.Println("居然不相等哎") }
|
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 居然不相等哎 ``` #### case 3 ```go type Value struct { Name string Hobby []string } func main() { v1 := Value{Name: "viola", Hobby: []string{"睡觉","发呆"}} v2 := Value{Name: "viola", Hobby: []string{"睡觉","发呆"}} if v1 == v2 { fmt.Println("居然相等哎") return } fmt.Println("居然不相等哎") }
|
运行结果:
1
| invalid operation: v1 == v2 (struct containing []string cannot be compared)
|
嘚,直接报错
那我们总结一下吧~ 为什么有时候可以直接比较,结果还是相等,而有时候比较不相等,有时间甚至接报错呢?
总结一下:
- 当 struct 中包含
slice
、map
、function
时,是不能直接比较的,会出现 case3 中的报错的情况
- 而指针引用,本来具体返回的地址就不是一样的,所以比较一定也是不相等的。
那么如果真的有slice
等,又需要比较,怎么办呢?使用 reflect.DeeqEqual
,其规则如下:
- 相同类型的值,是深度相等的,不同类型的值,永远不会深度相等。
- 当数组值对应的元素深度相等时,数组值是深度相等的。
- 当结构体值如果其对应的字段(包括导出和未导出的字段),都深度相等的,则该值是深度相等的。
- 当函数值如果都是 0,则深度相等;否则就不是深度相等
- 当接口值如果持有深度相等的具体值,则深度相等。