1.大前提
切片之间不允许用==比较,切片只能与nil值比较。
map之间不允许用==比较,map只能与nil值比较。所以:结构体的里面要是含有
切片,map那必定编辑就会报错
2.结构体中 不含指针变量含有切片变量 的比较方法
type Value struct {
Name string
GoodAt []string//注定 Value 结构体不能用==比较
}
type A struct {
a int
b string
}
func f1() {
//f1相等
v1 := Value{Name: "煎鱼", GoodAt: []string{"炸", "煎", "蒸"}}
v2 := Value{Name: "煎鱼", GoodAt: []string{"炸", "煎", "蒸"}}
aa := A{a: 1, b: "test1"}
bb := A{a: 1, b: "test1"}
f1 := A{a: 15}
f2 := A{}
f4 := A{}
f5 := A{}
fmt.Println(f1 == f2) //不相等
fmt.Println(aa == bb) //相等,【双等号在没有指针的结构体里只关心对应变量值一不一样】
fmt.Println(f4 == f5) //相等
//fmt.Println(v1 == v2) //因为Value结构体中含有切片,而切片是不知处==比较的
if reflect.DeepEqual(v1, v2) {
fmt.Println("两结构体相等")//相等
fmt.Println("----------------------------------------------------1")
} else {
fmt.Println("两结构体不等")
fmt.Println("----------------------------------------------------1")
}
}
func f6() {
aa := A{}
bb := A{}
fmt.Println(aa == bb)//true
}
3.结构体中 含指针变量 的比较方法
type Value3 struct {
Name string
Gender *string
}
func f3() {
//f3相等
//深度比较的时候会忽略new的不同地址,看内容是不是一致的
//此时v1,v2的Gender的地址虽不同(已被reflect.DeepEqual自动忽略),但是里面的内容都是空字符串
v1 := Value3{Name: "煎鱼", Gender: new(string)}
v2 := Value3{Name: "煎鱼", Gender: new(string)}
fmt.Println(v1.Gender)
fmt.Println(v2.Gender)
if reflect.DeepEqual(v1, v2) {
fmt.Println("两结构体相等")//相等
fmt.Println("----------------------------------------------------3")
} else {
fmt.Println("两结构体不等")
fmt.Println("----------------------------------------------------3")
}
}
func f4() {
//f4不相等
//是因为 t 和 e 的内容是不同的
t := "bbbb"
a1 := new(string)
fmt.Println(1, a1)
println(2, a1)
a1 = &t
e := "aaa"
y := new(string)
fmt.Println(y)
println(y)
y = &e
v1 := Value3{Name: "煎鱼", Gender: a1}
v2 := Value3{Name: "煎鱼", Gender: y}
fmt.Println(v1.Gender)
fmt.Println(v2.Gender)
if reflect.DeepEqual(v1, v2) {
fmt.Println("两结构体相等")
fmt.Println("----------------------------------------------------4")
} else {
fmt.Println("两结构体不等")//不相等
fmt.Println("----------------------------------------------------4")
}
}
func f5() {
//f5不相等
//是因为 t 和 e 的使用的是==比较的
//双等号的比较是严格比较地址的
t := "bbbb"
a1 := new(string)
a1 = &t
e := "bbbb"
y := new(string)
y = &e
v1 := Value3{Name: "煎鱼", Gender: a1}
v2 := Value3{Name: "煎鱼", Gender: y}
fmt.Println(v1.Gender)
fmt.Println(v2.Gender)
if v1 == v2 {
fmt.Println("两结构体相等")
fmt.Println("----------------------------------------------------5")
} else {
fmt.Println("两结构体不等")//不相等,【双等号在有指针变量的结构体中,指针不指同一处就不同】
fmt.Println("----------------------------------------------------5")
}
}
总结起来就是:比较结构体根据是不是重视地址来选比较方法
1.重视地址的不同,直接用等号
2.忽略地址不同,用反射的方法【reflect.DeepEqual】
3.1进阶比较
【reflect.DeepEqual】对于有地址 和 无地址是不会忽略的
package main
import (
"fmt"
"reflect"
)
type person struct {
name string
age *int
}
func main() {
var p person
p2 := person{
age: new(int),
}
fmt.Println(p.age) //空指针
fmt.Println(p2.age) //有地址,没内容
p3 := person{
age: new(int),
}
if reflect.DeepEqual(p, p2) {
fmt.Println("p,p2两者相等")
} else {
fmt.Println("p,p2两者不相等") //都有地址看内容,有地址 与 无地址 比较直接不相等
}
if reflect.DeepEqual(p2, p3) {
fmt.Println("p2,p3两者相等") //相等
} else {
fmt.Println("p2,p3两者不相等")
}
}