It's not really for efficiency, but rather for correctness – two instances
of a mutable type that happen to have the same field values are still not
the same object since it's quite easy to write code that distinguishes them
by mutating one but not the other. Moreover, if you put a mutable object
into a dict and then change one of its fields and its hash depended on that
field value, then it will be "lost" in the sense that if you check for
that *same
object* being in the dict, it will appear not to be, since it no longer
ends up in the same hash bucket.

On Sat, Feb 21, 2015 at 5:45 AM, Milan Bouchet-Valat <nalimi...@club.fr>
wrote:

> Le vendredi 20 février 2015 à 18:40 -0800, Tom Colvin a écrit :
> > I get a "key not found" error even though the key is clearly in there.
> > Here's a stripped down version of the code that produces the error:
> >
> > # Define my custom type
> > type Test
> >   act::Array{Int64}
> >   obs::Array{Int64}
> > end
> >
> > # Have to define an equality operator for the new type
> > import Base
> > Base.(:(==))(a::Test, b::Test) = (
> >   function (a::Test, b::Test)
> >     (a.act == b.act) && (a.obs == b.obs)
> >   end ) (a,b)
> >
> > # Make a Test, use it as a key in a dictionary,
> > #  then make a new test that is known to be in the dict
> > myTest = Test([1], [1])
> > test2ID = Dict([myTest=>1])
> > myTestCopy = deepcopy(myTest)
> >
> > # These work
> > test2ID[myTest]                        # 1
> > myTest in keys(test2ID)                # true
> > myTestCopy in collect(keys(test2ID))   # true
> > myTest == myTestCopy                   # true
> >
> > # These fail
> > test2ID[myTestCopy]           # error: key not found
> > myTestCopy in keys(test2ID)   # false
> >
> > So if I index with the original object that I created the dict from,
> > then it works.  If I have created a new and identical object, I get
> > "key not found" when I index by the new object AND it doesn't appear
> > in the keys() of the dictionary.  Puzzlingly, if the keys() are
> > collect()ed then it is indeed found.
> >
> > I suspect this is a bug, but wanted to check with the community before
> > opening an issue on github.  Am I doing something wrong?
> For efficiency, during a dict lookup keys are not tested for equality
> using ==, but using hashes. By default, types are hashed using the
> memory address of the object. I think you need to define your custom
> hash() function by recursively hashing its fields. See ?hash.
>
>
> Regards
>
>

Reply via email to