Хеш-функция для пользовательского типа - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь определить собственный метод равенства для нового типа, который я построил. Это MWE понимает, что я пытаюсь сделать.

mutable struct a
    first_num::Int
    second_num::Int
end

import Base.==
import Base.hash
function hash(obj::a, h=33141651)
    return hash((obj.first_num, obj.second_num), h)
end

function ==(obj1::a, obj2::a)
    if hash(obj1) == hash(obj2)
        return true
    else
        return false
    end
end

a1 = a(2,3)
a2 = a(2,3)
a1 == a2

Я тогда получаю сообщение об ошибке типа ERROR: TypeError: ==: in typeassert, expected UInt64, got Int64

h становится Int64?

Кроме того, если хеширование набора атрибутов просто не правильный способ сделать это, дайте мне знать.

Редактировать: На самом деле, я запустил это, и я получаю MethodError: no method matching hash(::Tuple{Int64,Int64}, ::Int64). h повышен до Int64?

1 Ответ

0 голосов
/ 27 апреля 2018

Проблема в том, что ваше буквальное значение для h (33141651) является Int, а не UInt. Таким образом, при вызове hash с кортежем h является Int, но внутренняя функция кортежа hash ожидает UInt. Я не думаю, что вам вообще нужно указывать значение для h, и что-то вроде этого должно быть достаточно:

function Base.hash(obj::a, h::UInt)
    return hash((obj.first_num, obj.second_num), h)
end

Полный пример полноты:

mutable struct A
    first::Int
    second::Int
end

function Base.hash(obj::A, h::UInt)
    return hash((obj.first, obj.second), h)
end

function Base.:(==)(obj1::A, obj2::A)
    return hash(obj1) == hash(obj2)
end

Со следующим поведением

julia> a = A(2,3); b = A(2,3)
A(2, 3)

julia> hash(a)
0x965b43497b212144

julia> hash(b)
0x965b43497b212144

julia> a == b
true
...