I make a custom composite type (or structure), make two objects of that type, and test if they're equal:
struct mytype
stuff::Int64
end
a = mytype(5)
b = mytype(5)
a == b
true
This works as I expected. However, if we make the contents a vector instead, comparing a
and b
returns false:
struct mytype2
stuff::Vector{Int64}
end
a = mytype2([5])
b = mytype2([5])
a == b
false
a === b
false
isequal(a, b)
false
Any idea why this is? Is there a way to compare a
and b
in the second case, when they contain a vector?
The built-in (meaning you can't add methods) function ===
compares mutable structs by address and immutable structs by content. a === b
is false
because your immutable a
and b
contain two different arrays' addresses, so their contents are different. a.stuff === b.stuff
is false
because the arrays are separate with their own addresses.
Then there is ==
, a function that you CAN add methods to. By default, it falls back to ===
, and the question "should ==
be recursive by default" is still an open issue for Julia v2 (4648). For now, it's expected that you write your own ==
methods for your own types. In fact, a.stuff == b.stuff
is true
because there are ==
methods specifically for Array
s of Number
s. So the simplest way for your type would be:
Base.:(==)(a::mytype2, b::mytype2) = a.stuff == b.stuff
In practice, your composite type probably has more fields so writing this stuff gets tedious. Issue 4648 includes a post (Jan 15 2021) of a generated function structEqual
that does ==
on all fields of a struct, though I personally haven't tried it out.