golang的struct能否比较
【摘要】 golang的struct能否比较指golang中的struct能否通过 ==或!== 进行比较,需要注意什么问题,可以分哪些类型1.数据类型golang中能够用 == 号直接比较的数据类型有如下整型 integer、浮点型 float、字符串 string、布尔型 boolean、复数型 complex、指针型 pointer、通道型 channel、接口型 interface、数组型 a...
golang的struct能否比较
指golang中的struct能否通过 ==或!== 进行比较,需要注意什么问题,可以分哪些类型
1.数据类型
golang中能够用 == 号直接比较的数据类型有如下
- 整型 integer、浮点型 float、字符串 string、布尔型 boolean、复数型 complex、指针型 pointer、通道型 channel、接口型 interface、数组型 array
不能直接比较的
- 切片型 slice、键值对型 map、函数型 func
2.struct比较
1.相同结构体+可比较类型
package main
import "fmt"
type S struct {
s string
i int
b bool
}
func main() {
s1 := S{
s: "你好",
i: 1,
b: false,
}
s2 := S{
s: "你好",
i: 1,
b: false,
}
fmt.Println(s1 == s2)
}
//结果:
true
结构体内都是可比较的类型,赋值两个一样数据的struct,最终两个struct是相等的,返回true
package main
import "fmt"
type S struct {
s string
i int
b bool
p *int
}
func main() {
s1 := S{
s: "你好",
i: 1,
b: false,
p: new(int),
}
s2 := S{
s: "你好",
i: 1,
b: false,
p: new(int),
}
fmt.Println(s1 == s2)
fmt.Println(s1.p)
fmt.Println(s2.p)
}
//结果
false
0xc000018080
0xc000018088
加了指针类型后依然可以直接比较,但是为什么会返回false呢?因为在初始化s1和s2的时候给p初始化了,两个指针的地址是不同的,导致返回false
如果不给p赋值,则地址为nil,或者赋同一个值,则会返回true,如下
package main
import "fmt"
type S struct {
s string
i int
b bool
p *int
}
func main() {
pp := new(int)
*pp = 123
s1 := S{
s: "你好",
i: 1,
b: false,
p: pp,
}
s2 := S{
s: "你好",
i: 1,
b: false,
p: pp,
}
fmt.Println(s1 == s2)
fmt.Println(s1.p)
fmt.Println(s2.p)
}
//结果
true
0xc00010c008
0xc00010c008
可见此时s1和s2指针的地址是相同的
2.相同结构体+不可比较类型
package main
import "fmt"
type S struct {
s string
i int
b bool
slice []int
}
func main() {
s1 := S{
s: "你好",
i: 1,
b: false,
slice: []int{1, 2},
}
s2 := S{
s: "你好",
i: 1,
b: false,
slice: []int{1, 2},
}
fmt.Println(s1 == s2)
//此时编译都无法通过,报错误,因为结构体里包含不可比较类型切片 []int
}
//结果
# command-line-arguments
./01_go_struct_compare.go:27:17: invalid operation: s1 == s2 (struct containing []int cannot be compared)
那么有什么办法可以让两个包含不可比较类型的结构体比较吗?可以通过 reflect.DeepEqual 函数
package main
import (
"fmt"
"reflect"
)
type S struct {
s string
i int
b bool
slice []int
}
func main() {
s1 := S{
s: "你好",
i: 1,
b: false,
slice: []int{1, 2},
}
s2 := S{
s: "你好",
i: 1,
b: false,
slice: []int{1, 2},
}
fmt.Println(reflect.DeepEqual(s1, s2))
}
//结果
true
reflect.DeepEqual函数深度比较的规则
-
不同类型的值永远不会完全相等
-
当数组值的对应元素深度相等时,数组值深度相等
-
如果结构体的相应字段深度相等,则结构体深度相等
-
如果func都为nil,则func深度相等,否则不会深度相等
-
切片深度相等的条件
- 它们都是 nil 或都非 nil,且具有相同的长度
- 非 nil 空切片和 nil 切片(例如,[]byte{} 和 []byte(nil))并不完全相等
- 指向同一底层数组的初始位置要相同(即 &x[0 ] == &y[0]) 或其对应的元素(直到末尾)深度相等
-
指针深度相等的条件
- 指针值使用 Go 的 == 运算符相等
- 它们指向深度相等的值,则它们是深度相等的
-
映射值map深度相等的条件
- 它们都是 nil 或都非 nil,且具有相同的长度
- 它们是相同的映射对象,或者它们对应的键(使用 Go 相等性匹配)映射到深度相等的值
3.不同结构体+可比较类型
可以通过强制类型转换的方式来进行比较
package main
import "fmt"
type S1 struct {
s string
i int
b bool
p *int
}
type S2 struct {
s string
i int
b bool
p *int
}
func main() {
var s1 S1
var s2 S2
//s1 = s2 //报错,无法直接赋值
s3 := S1(s2)
fmt.Println(s3 == s1)
}
//结果
true
4.不同结构体+不可比较类型
package main
import "fmt"
type S1 struct {
s string
i int
b bool
p *int
slice []int
}
type S2 struct {
s string
i int
b bool
p *int
slice []int
}
func main() {
var s1 S1
var s2 S2
s3 := S1(s2)
fmt.Println(s3 == s1)
}
//结果
# command-line-arguments
./02_go_struct_compare.go:26:17: invalid operation: s3 == s1 (struct containing []int cannot be compared)
可见如果结构体里包含了不可比较类型,则无法通过强制类型转换的方式进行比较
5.struct作为map的key
struct里面的类型必须是可比较的,才能作为map的key,否则会报错,无法通过编译
package main
import "fmt"
type S1 struct {
s string
i int
b bool
p *int
slice []int
}
func main() {
m := make(map[S1]string, 0) //编译出错
fmt.Println(m)
}
//结果
# command-line-arguments
./02_go_struct_compare.go:27:12: invalid map key type S1
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)