Define equality for struct by checking all fields

I find myself in the position of defining various structs of the form

struct Foo{T, U}
 bar::T
 bar2::U
end

where I want to define Foo(a,b) == Foo(c,d) iff a == c and b == d. I can do this manually:

Base.:(==)(op1::Foo, op2::Foo) = op1.bar == op2.bar && op1.bar2 == op2.bar2

However, if I have many structs, each with several fields, this becomes a bit tedious. Is there a way to do this automatically through a macro or something?

No built-in way unfortunately (see this issue).
Use a package, eg GitHub - jw3126/StructHelpers.jl: Automate common struct definition boilerplate :

using StructHelpers

struct S
    a
    b
end

@batteries S
3 Likes

That is a bit inconvenient indeed, you’d expect there to be some base macro for this. Thanks for the pointer!

You can also do this, depending on the complexity of the structures:

julia> struct A
           x
           y
       end

julia> a = A(1,2); b = A(1,2)
A(1, 2)

julia> import Base: ==

julia> ==(a::A,b::A) = all(getfield(a,f) == getfield(b,f) for f in fieldnames(A))
== (generic function with 198 methods)

julia> a == b
true

5 Likes

An alternative, using @lmiq’s example:

getfield.(Ref(a), fieldnames(A)) == getfield.(Ref(b), fieldnames(A))
1 Like