avatar

目录
结构体能否比较呢?

golang 的结构体也就是 struct 能否比较呢?

直接说结论,是要分情况的,也就是要看 struct 中究竟存储的数据类型。

case 1

go
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("居然不相等哎")
}

输出结果:

go
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("居然不相等哎")
}

输出结果:

go
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("居然不相等哎")
}

运行结果:

go
1
invalid operation: v1 == v2 (struct containing []string cannot be compared)

嘚,直接报错


那我们总结一下吧~ 为什么有时候可以直接比较,结果还是相等,而有时候比较不相等,有时间甚至接报错呢?
总结一下:

  • 当 struct 中包含 slicemapfunction时,是不能直接比较的,会出现 case3 中的报错的情况
  • 而指针引用,本来具体返回的地址就不是一样的,所以比较一定也是不相等的。

那么如果真的有slice等,又需要比较,怎么办呢?使用 reflect.DeeqEqual,其规则如下:

  1. 相同类型的值,是深度相等的,不同类型的值,永远不会深度相等。
  2. 当数组值对应的元素深度相等时,数组值是深度相等的。
  3. 当结构体值如果其对应的字段(包括导出和未导出的字段),都深度相等的,则该值是深度相等的。
  4. 当函数值如果都是 0,则深度相等;否则就不是深度相等
  5. 当接口值如果持有深度相等的具体值,则深度相等。
文章作者: Viola Tangxl
文章链接: https://violatangxl.github.io/2021/06/04/golang-struct-compare/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 椰子是只猫
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论