有没有办法超载如何Base.Set
在Julia中进行对象比较?
我试着超载isequal
和==
,但我的对象仍标记为不同的时,他们应该是相同的.
例如
type Test
x
y
end
function ==(a::Test, b::Test)
return a.x == b.x && a.y == b.y
end
Set([Test(2,3), Test(2,3)])
Run Code Online (Sandbox Code Playgroud)
给
Set([Test(2,3),Test(2,3)])
Run Code Online (Sandbox Code Playgroud)
复合类型比较有一个有用的包,AutoHashEquals:
using AutoHashEquals
@auto_hash_equals type Test
x
y
end
X = Test(2, 3)
Y = Test(2, 3)
Z = Test(1, 3)
X == Y # = true
X == Z # = false
Set([X, Y, Z]) # = Set([Test(2,3),Test(1,3)])
Run Code Online (Sandbox Code Playgroud)
但是,就像@ Gnimuc-K所指出的那样"这个宏只有当它们被用作不可变记录时才对可变类型有用."
ASet
是一种Dict
具有以下类型值的Void
: ref
type Set{T} <: AbstractSet{T}
dict::Dict{T,Void}
Set() = new(Dict{T,Void}())
Set(itr) = union!(new(Dict{T,Void}()), itr)
end
Run Code Online (Sandbox Code Playgroud)
Julia -lang 文档描述Dic
类型如下:
Dict 是标准的关联集合。它的实现使用 hash() 作为键的散列函数,并使用 isequal() 来确定相等性。为自定义类型定义这两个函数以覆盖它们在哈希表中的存储方式。
检查dict.jl,并查找ht_keyindex2()
和ht_keyindex()
函数。index
仅当这两个条件满足时,两者才会返回true
:
if !isslotmissing(h,index) && isequal(key,keys[index])
return index
end
Run Code Online (Sandbox Code Playgroud)
上面的内容:index = hashindex(key, sz)
Julia 使用hash()
函数执行哈希任务:
hash(x[, h])
计算一个整数哈希码,使得 isequal(x,y) 意味着 hash(x)==hash(y)。可选的第二个参数 h 是要与结果混合的哈希码。新类型应该实现 2 参数形式,通常通过递归调用 2 参数哈希方法来将内容的哈希值相互混合(以及与 h 混合)。通常,任何实现 hash 的类型也应该实现自己的 ==(因此 isequal)以保证上述属性。
因此,通过这些准备工作,很明显,重写Base.==
, 不是完成任务的正确且完整的方法,但是
hash()
函数以返回相同的hashindex
值Base.==
它足以覆盖Base.isequal
代码:
type Test
x
y
end
Base.hash(a::Test, h::UInt) = hash(a.y, hash(a.x, hash(:Test, h)))
Base.isequal(a::Test, b::Test) = Base.isequal(hash(a), hash(b))
Set([Test(2,3), Test(2,3)])
Run Code Online (Sandbox Code Playgroud)
重点是,尽管Test(2,3) == Test(2,3) #=> false
它按预期工作。