首先我们知道,一般来说相同的数据类型是可以进行比较的,但是在Go里面有三种数据类型是不能进行比较的:

  • 切片(slice)
  • 函数
  • map

也就是说基本的数据结构,除了这三种,其他都是可以进行比较的

能比较的struct

我们来以下代码

type testCompare struct {
    a int
    b string
    c *int
}

func main() {
    t1 := testCompare{
        a: 1,
        b: "1",
        c: new(int),
    }

    t2 := testCompare{
        a: 1,
        b: "1",
        c: new(int),
    }

    fmt.Println(t1 == t2)
}

这段代码可以输出结果吗,还是说会报错,答案是可以输出结果,结果为false

为什么可以进行比较

当两个变量都是同一个struct的时候,同时struct内部的属性没有不可比较的数据类型,那么它两就可以进行比较

为什么输出的结果会是false

那是因为c那个地方的内存地址是不同的,所以t1t2也就不相等。

不能比较的struct

那么根据上面的说法,咱们再来看下面这段代码,输出的结果

type test struct {
   a int
   b string
   c []int
}

func main() {
   t1 := test{
      a: 1,
      b: "b",
      c: []int{1,2,3},
   }
   t2 := test{
      a: 1,
      b: "b",
      c: []int{1,2,3},
   }
   fmt.Println(t1 == t2)
}

结果是在编译的时候就会给你报红了,因为在这个struct里面存在不可比较的slice,所以只要struct里面存在一个不可比较的变量,那么这个struct就不能通过==的方法来比较了。`

不可比较的struct真的不可比较吗?

正如题目所说的,只要struct里面存在了不可比较的数据类型,那么它就在真的没办法比较了吗,其实也不是,正如我说的:struct就不能通过==的方法来比较大小,但是Go中却提供了一个方法可以让我们方便比较内部存在不可比较数据类型 —— reflect.DeepEqua

我们只需要把上面的代码做如下的更改,就可以比较了

type test struct {
   a int
   b string
   c []int
}

func main() {
   t1 := test{
      a: 1,
      b: "b",
      c: []int{1,2,3},
   }
   t2 := test{
      a: 1,
      b: "b",
      c: []int{1,2,3},
   }
   fmt.Println(reflect.DeepEqual(t1,t2))
}

而且输出的也会是true

两个不同的struct能不能比较

上面提到的都是同样的struct,那么如果是两个不同的strcut它们能不能进行比较呢

例如我们同样的使用reflect.DeepEqual的方法来进行比较下面的代码

type test struct {
   a int
   b string
   c []int
}

type test1 struct {
   a int
   b string
   c []int
}

func main() {
   t1 := test{
      a: 1,
      b: "b",
      c: []int{1,2,3},
   }
   t2 := test1{
      a: 1,
      b: "b",
      c: []int{1,2,3},
   }
   fmt.Println(reflect.DeepEqual(t1,t2))
}

输出的结果将会变成false,这个也非常好理解,两个完全的不同的类,纵使你里面的数据类型完全相同,它也是两个完全不同的个体,肯定是不一样的。

那么有没有办法真正的不会受到struct不同的干扰,而是可以直接去比较内部的数据类型呢。

强行比较(类型强转)

我们只需要对上面的代码做一些改造

type test struct {
   a int
   b string
}

type test1 struct {
   a int
   b string
}

func main() {
   var t1 test
   var t2 test1
   t3 := test1(t1)
   fmt.Println(t2 == t3)
}

只需要同类型强转的方式,就可以让两个不同类型的struct进行比较了,但是这里有个大前提,就是前面提到的,struct内部不能存在不可比较的数据类型

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:https://www.ltfred.com/article/go-struct-compare/