结构体怎么作比较???

127 阅读2分钟

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两者不相等")
   }

}