I see that julia has 3 different ways to do equality.
==
, ===
, and isequal
Which should I use, and when?
I see that julia has 3 different ways to do equality.
==
, ===
, and isequal
Which should I use, and when?
===
is the built-in equality.In all 3 cases this is all more or less just bit-level equality, references to memory are pointers. (But of fancyness to make the immutable struct version recursive)
Ideally, one wouldn't use this much, because it is not customizable. Sometimes though it is good to use because the optimizer can reason about it really well, so it can lead to better performance for hot loops.
==
is general purpose equalityIt is overloadable.
For Floats it follows the IEEE rules, i.e. -0.0 == 0.0
, NaN != NaN
.
And it follows 3 values logic rules for missing == missing
resulting in missing
.
if ==
is not defined then it falls back to ===
If you have defined ==
, you need to define hash
as isequal
falls back to using ==
, see below.
isequal
is equality for purpose of dictionaries.I don't know a much better way to put it.
Things that are isequal
are considered the same for purposes of Dict
and Set
.
So you can't have two items that are isequal
as distinct keys in a Dict
.
Use this if you want to be sure that NaN
s are equal to each other,
and similarly that missings are equal to each other.
When defining isequal
you also must define hash
.
isequal(a, b)
implies hash(a) == hash(b)
If isequal
is not defined, then it falls back to ==
Basically:
==
when you are interested in the values of two objects: 1 == 1
->true
and 1 == 1.0
->true
===
when you want to make sure that two objects cannot be distinguished (including arrays pointing to different memory): 1 === 1
->true
but 1 === 1.0
->false
and A = [1, 2, 3]; B = [1, 2, 3]
leads to A == B
->true
but A === B
->false
(A === A
->true
).isequal()
same as ==
but handles floating point numbers differently: NaN == NaN
->false
but isequal(NaN, NaN)
->true
.A deeper discussion here.