添加到Julia中的集合时是否重载对象?

tln*_*agy 3 types julia

有没有办法超载如何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)

amr*_*ods 5

复合类型比较有一个有用的包,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所指出的那样"这个宏只有当它们被用作不可变记录时才对可变类型有用."


Rez*_*lan 4

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.==, 不是完成任务的正确且完整的方法,但是

  1. 我们需要重写hash()函数以返回相同的hashindex
  2. 相反,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它按预期工作。