Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine struct equality based on fields and not struct types in Golang?

I am currently using the go-cmp package to compare struct equality. For testing purposes I have the need to compare two different types of structs that should have the same fields with the same values.

As a minimal example I am running into the issue where the cmp.Equal() function returns false for different types, even though they have the same fields and values.

type s1 struct {
    Name string
}

type s2 struct {
    Name string
}

p1 := s1{Name: "John"}
p2 := s2{Name: "John"}

fmt.Println(cmp.Equal(p1, p2)) // false

This is understandable since the two types are different but is there a way to instruct cmp.Equal() to ignore the types and only look at fields?

like image 779
Loupi Avatar asked Oct 17 '25 08:10

Loupi


2 Answers

I don't know if you can omit types during comparison, but if 2 struct types have identical fields, you can convert one to the other type, so this won't be an issue:

p1 := s1{Name: "John"}
p2 := s2{Name: "John"}

fmt.Println(cmp.Equal(p1, p2)) // false
fmt.Println(cmp.Equal(p1, s1(p2))) // true

Try it on the Go Playground.

like image 58
icza Avatar answered Oct 19 '25 00:10

icza


Here is one way to compare fields without their type through json.Marshal and json.Unmarshal to interface type.

    type s1 struct {
        Name string
    }

    type s2 struct {
        Name string
    }

    p1 := s1{Name: "John"}
    p2 := s2{Name: "John"}

    fmt.Println(cmp.Equal(p1, p2)) // false

    var x1 interface{}
    b1, _ := json.Marshal(p1)
    _ = json.Unmarshal(b1, &x1)

    var x2 interface{}
    b2, _ := json.Marshal(p2)
    _ = json.Unmarshal(b2, &x2)

    fmt.Println(cmp.Equal(x1, x2)) // true

Playground sample

like image 37
zangw Avatar answered Oct 19 '25 00:10

zangw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!