Julia复合类型中的哈希不稳定性

Ben*_*ner 6 julia

在Julia中,具有至少一个具有相同值的字段的复合类型将散列到不同的值.这意味着如果将复合类型用作字典键或任何依赖于散列值的其他内容,则复合类型无法正常工作.此行为与其他类型的行为不一致,例如Vector {Int}.

更具体地说,

非复合类型的向量是不同的对象但具有相同的值哈希到相同的值:

julia> hash([1,2,3])==hash([1,2,3])
true
Run Code Online (Sandbox Code Playgroud)

没有字段散列到相同值的复合类型:

julia> type A end
julia> hash(A())==hash(A())
true
Run Code Online (Sandbox Code Playgroud)

复合类型,如果它们是具有相同值的不同对象,则至少有一个字段哈希到不同的值:

julia> type B
           b::Int
       end
julia> hash(B(1))==hash(B(1))
false
Run Code Online (Sandbox Code Playgroud)

但是,即使基础值发生更改,同一对象也会维护其哈希值:

julia> b=B(1)
julia> hash(b)
0x0b2c67452351ff52

julia> b.b=2;
julia> hash(b)
0x0b2c67452351ff52
Run Code Online (Sandbox Code Playgroud)

这与向量的行为不一致(如果更改元素,则哈希更改):

julia> a = [1,2,3];
julia> hash(a)
0xd468fb40d24a17cf

julia> a[1]=2;
julia> hash(a)
0x777c61a790f5843f
Run Code Online (Sandbox Code Playgroud)

不可变类型不存在此问题:

julia> immutable C
           c::Int
       end
julia> hash(C(1))==hash(C(1))
true
Run Code Online (Sandbox Code Playgroud)

从语言设计的角度来看,是否有一些基本的推动这种行为?有计划修复或纠正这种行为吗?

Seb*_*ood 7

我不是朱莉娅语言设计师,但我会说这种行为在比较可变和不可变的值时并不奇怪.你的类型B是可变的:它的两个实例,即使它们具有相同的字段值,也不是很明显b,应该被认为是相等的.如果您认为应该是这种情况,您可以自由地为它实现哈希函数.但一般来说,可变对象具有独立的身份.不可变的实体,如C不可能彼此分开,因此它们服从结构哈希是有意义的.

恰好有5美元的两个银行账户并不相同,可能不应该使用相同的数字.但两个5美元的实例无法相互区分.

  • 发现,这就是为什么这是默认行为. (4认同)