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 structs 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
xandyare 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