Weird hash behavior

I have a custom type, and I defined == for it. I’m trying to delete! one member in a OrderedDict but it doesn’t work. I traced down the problem to the following behavior:

using DataStructures
import Base: ==
n = 2
type A
    x::Int
end
==(a1::A, a2::A) = a1.x == a2.x
a = OrderedSet(A(i - 3) for i = 1:n)
a1 = A(-2)
@assert a1 == a[1] # checks out
@assert hash(a1) == hash(a[1]) # doesn't!

So why does the hash of a1 and a[1] not the same? Or how can I delete! things that are ==?

Thanks!

The default hash of a type object is the hash of its pointer. a1 === a[1] is false (they are different objects) so they hash to different values. You should usually define Base.hash whenever you define a custom ==.

Or you could use an immutable; then the default equality and hash are already what you want.

For most cases AutoHashEquals.jl is a very compact solution.

2 Likes

Ah…! I see. Thanks!

OK, immutable just takes care of all of that. But I might not be able to implement a immutable type conveniently, in which case I’ll use AutoHashEquals.jl.