Julia:包含包含复合类型的元组键的字典

Julia:包含包含复合类型的元组键的字典,julia,Julia,我在尝试使用一个字典时遇到了一个问题,该字典的键是包含复合类型的元组 下面是一个复制我的问题的简单示例: import Base: hash, isequal type T a :: Int b :: Int end function isequal(A::(T,Int), B::(T,Int)) A[1].a == B[1].a && A[1].b == B[1].b && A[2] == B[2] end function

我在尝试使用一个字典时遇到了一个问题,该字典的键是包含复合类型的元组

下面是一个复制我的问题的简单示例:

import Base: hash, isequal    

type T
    a :: Int
    b :: Int
end

function isequal(A::(T,Int), B::(T,Int))
    A[1].a == B[1].a && A[1].b == B[1].b && A[2] == B[2]
end
function hash(A::(T,Int))
    hash(A[1].a + A[1].b + A[2])
end

d = Dict{(T,Int),Int}()

d[(T(1,1),1)] = 1
d[(T(2,2),2)] = 2

r = (T(2,2),2)

for k in keys(d)
    println(isequal(r, k) && hash(r) == hash(k))
end
println(d[r])
运行此命令将导致:

false
true
ERROR: key not found: (T(2,2),2)
因此,
isequal
hash
起作用,但由于某些原因,dict不起作用


有人知道发生了什么事吗?谢谢。

在本例中,关于元组类型和分派,我不太了解,但基本上是这样。作为比较,以下非常类似的代码在没有两个参数形式的情况下按预期工作:

type T
    a::Int
    b::Int
end

function Base.isequal(A::T, B::T)
    println("isequal", A, " ", B)
    A.a == B.a && A.b == B.b
end
function Base.hash(A::T)
    println("hash", A)
    hash(A.a + A.b)
end

d = Dict{T,Int}()

d[T(1,1)] = 1
d[T(2,2)] = 2

println("test")
r = T(2,2)
println(d[r])
有输出

isequalT(1,1) T(1,1)
hashT(1,1)
isequalT(2,2) T(2,2)
hashT(2,2)
test
hashT(2,2)
isequalT(2,2) T(2,2)
2

这个问题可以通过为每个复合类型而不是整个元组创建
散列
&
等质量
函数来解决

如果您的键是
(T,Int)

与此相反:

function isequal(A::(T,Int), B::(T,Int))
    A[1].a == B[1].a && A[1].b == B[1].b && A[2] == B[2]
end
function hash(A::(T,Int))
    hash(A[1].a + A[1].b + A[2])
end
这样做:

function isequal(A::T, B::T)
    A.a == B.a && A.b == B.b
end
function hash(A::T)
    hash(A.a + A.b)
end
如果希望原始公式起作用,则必须使用可选的第二个参数指定Base.hash:
h::Uint64

function isequal(A::(T,Int), B::(T,Int))
    A[1].a == B[1].a && A[1].b == B[1].b && A[2] == B[2]
end
function hash(A::(T,Int))
    hash(A[1].a + A[1].b + A[2])
end
function hash(A::(T,Int), h::Uint64)
    hash(A[1].a + A[1].b + A[2] + h)
end

我在
isequal
hash
中添加了一些打印语句。由于某种原因,添加到dict会导致它调用
isequal
(为什么不哈希?),并且使用
d[r]
检查dict不会导致调用其中任何一个。应导入哈希和isequal以使其重载。import语句不在代码段中(它在下面的Iain中)。这是否解释了差异?您认为它们需要导入是正确的。我确实有,但应该放在那里。我会加上它。有趣。我使用的是0.3.1版(2014-09-21:30 UTC),请注意,您使用dict运行它,其中键是T类型。我的示例中有一个dict,其中键是元组:(T,Int)。你能试着运行它吗?是的,我是说我可以重新创建你的问题,而这个问题不会发生在这个非常类似的例子中。我的观点是,我认为你应该提出JuliaLang/julia问题。我对我的答案进行了编辑,以使其更加清晰。但我不明白为什么原始问题中的版本不起作用?我只是偶然发现了正确的解决方案:事实证明,您必须实现哈希来支持可选的第二个参数
h::Uint64
。不确定为什么这一定会修复它,但它确实修复了。很好的一点,这在这里有记录:。我也更新了我的答案。