There is a behavior I don't understand when checking for equality in Julia concerning "struct" objects.
The documentation states : : "For collections, ==
is generally called recursively on all contents, though other properties (like the shape for arrays) may also be taken into account". Though it seems for structs it is cast to ===
or something.
Here is a minimal working exemple :
As expected :
string1 = String("S")
string2 = String("S")
string1 == string2
=> returns true
and :
set1 = Set(["S"])
set2 = Set(["S"])
set1 == set2
=> returns true
BUT ! And that is what I don't understand :
struct StringStruct
f::String
end
stringstruct1 = StringStruct("S")
stringstruct2 = StringStruct("S")
stringstruct1 == stringstruct2
=> returns true
However :
struct SetStruct
f::Set{String}
end
setstruct1 = SetStruct(Set(["S"]))
setstruct2 = SetStruct(Set(["S"]))
setstruct1 == setstruct2
=> returns false
To me, it looks like ===
is tested on the elements of the struct.
So my question is : what is the real behavior of ==
when tested on structs ? Does it cast ==
or ===
? In case it casts ==
as the documentation states, what is the point I misunderstand ?
For struct
s by default ==
falls back to ===
, so e.g.:
setstruct1 == setstruct2
is the same as
setstruct1 === setstruct2
So now we go down to the way how ===
works. And it is defined as:
Determine whether
x
andy
are identical, in the sense that no program could distinguish them.
(I am leaving out the rest of the definition, as I believe this fist sentence builds a nice mental model).
Now clearly stringstruct1
and stringstruct2
are non-distinguishable. They are immutable and contain strings that are immutable in Julia. In particular they have the same hash
value (which is not a definitive test, but is a nice mental model here).
julia> hash(stringstruct1), hash(stringstruct2)
(0x9e0bef39ad32ce56, 0x9e0bef39ad32ce56)
Now setstrict1
and setstruct2
are distinguishable. They store different sets, although at the moment of comparison these sets contain the same elements, but they have different memory locations (so in the future they can be different - in short - they are distinguishable). Note that these structs have different hashes in particular:
julia> hash(setstruct1), hash(setstruct2)
(0xe7d0f90913646f29, 0x3b31ce0af9245c64)
Now notice the following:
julia> s = Set(["S"])
Set{String} with 1 element:
"S"
julia> ss1 = SetStruct(s)
SetStruct(Set(["S"]))
julia> ss2 = SetStruct(s)
SetStruct(Set(["S"]))
julia> ss1 == ss2
true
julia> ss1 === ss2
true
julia> hash(ss1), hash(ss2)
(0x9127f7b72f753361, 0x9127f7b72f753361)
This time ss1
and ss2
are passing all the tests, as again they are indistinguishable (if you change ss1
then ss2
changes in sync as they hold the same Set
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With