During the weekend, I had a lot of interviews. Because I planned to transfer to Go, I was asked a question that left a deep impression on me — can I compare structs in Go

The answer was not particularly good, today I take time to summarize, convenient next time when the same problem can have a train of thought.

So in Go, structs can be compared, in fact, they can be compared, but not completely compared.

Here we have to look at the case by case

Struct that can be compared

First of all, we know that generally the same data type can be compared, but there are three data types in Go that cannot be compared:

  1. Slice
  2. function
  3. Map

That is, basic data structures, except for these three, are comparable.

So let’s take a look at the code below

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


func main(a)  {
   t1 := test{
      a:1,
      b:"b",
      c:new(int),
   }
   t2 := test{
      a:1,
      b:"b",
      c:new(int),
   }
   fmt.Println(t1 == t2)
}
Copy the code

Does this code output the result, or does it report an error, the answer is yes, the result is false

1. Why can comparisons be made

When two variables are the same struct and the struct has no non-comparable data types, they can be compared.

2. Why is the output false

That’s because c has a different memory address, so T1 and T2 are not equal.

Struct that cannot be compared

So with that said, let’s look at the output of this code

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

func main(a) {
   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)
}
Copy the code

The result is a red flag at compile time, because there is a non-comparable slice in the struct, so if there is a non-comparable variable in the struct, then the struct cannot be compared with the == method.

Are uncomparable structs really uncomparable?

If a struct has a data type that cannot be compared, then it cannot be compared. Structs cannot compare sizes using the == method, but Go provides a method to compare internal non-comparable data types — reflect.deepequa

We just need to make the following changes to the above code, and we can compare

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

func main(a) {
   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))
}
Copy the code

And the output will be true

Can you compare two structs that are not in use

All the structs mentioned above are the same struct, so can they be compared if they are two different strcuts

For example, we also use reflect.deepequal to compare the following code

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

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

func main(a) {
   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))
}
Copy the code

The result of the output will be true, and this is also very understandable, two completely different classes, even if you have the same data type in them, they are two completely different individuals, they are definitely different.

So is there a way to actually compare internal data types without being disturbed by struct differences?

Forced comparison (type coercion)

We just need to make some changes to the code above

type test struct {
   a int
   b string
}

type test1 struct {
   a int
   b string
}

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

Structs of different types can be compared with each other only by using a strong cast. However, there is a general requirement that there cannot be non-comparable data types inside structs.

The last

This is a common interview question, and I hope to summarize it for you as well