在 Julia 中递归检查结构的 `==` 吗?好像没有

Gom*_*B0T 4 struct julia

在 Julia 中检查关于“struct”对象的相等性时,有一种我不明白的行为。文档指出::“对于集合,==通常在所有内容上递归调用,但也可能考虑其他属性(如数组的形状) ”。虽然它似乎是结构体,但它被强制转换===为什么的。这是一个最小的工作示例:

正如预期的那样:

string1 = String("S")
string2 = String("S")
string1 == string2 
Run Code Online (Sandbox Code Playgroud)

=> 返回真

和 :

set1 = Set(["S"])
set2 = Set(["S"])
set1 == set2
Run Code Online (Sandbox Code Playgroud)

=> 返回真


但 !这就是我不明白的:

struct StringStruct
    f::String
end
stringstruct1 = StringStruct("S")  
stringstruct2 = StringStruct("S")  
stringstruct1 == stringstruct2  
Run Code Online (Sandbox Code Playgroud)

=> 返回真

然而 :

struct SetStruct  
    f::Set{String}  
end
setstruct1 = SetStruct(Set(["S"]))
setstruct2 = SetStruct(Set(["S"]))
setstruct1 == setstruct2 
Run Code Online (Sandbox Code Playgroud)

=> 返回假


对我来说,它看起来像是===对结构的元素进行了测试。

所以我的问题是:==在结构上测试时的真实行为是什么?它是投射==还是===?如果它==按照文档说明进行转换,我误解的重点是什么?

Bog*_*ski 8

对于structs 默认情况==下回退到===,因此例如:

setstruct1 == setstruct2
Run Code Online (Sandbox Code Playgroud)

是相同的

setstruct1 === setstruct2
Run Code Online (Sandbox Code Playgroud)

所以现在我们深入了解===工作原理。它被定义为:

确定xy是否相同,因为没有程序可以区分它们。

(我省略了定义的其余部分,因为我相信这第一句话建立了一个很好的心理模型)。

现在清楚stringstruct1stringstruct2不可区分。它们是不可变的,并且包含在 Julia 中不可变的字符串。特别是它们具有相同的hash值(这不是一个明确的测试,但在这里是一个很好的心理模型)。

julia> hash(stringstruct1), hash(stringstruct2)
(0x9e0bef39ad32ce56, 0x9e0bef39ad32ce56)
Run Code Online (Sandbox Code Playgroud)

现在setstrict1setstruct2是有区别的。它们存储不同的集合,虽然在比较时这些集合包含相同的元素,但它们具有不同的存储位置(因此将来它们可以不同 - 简而言之 - 它们是可区分的)。请注意,这些结构特别具有不同的哈希值:

julia> hash(setstruct1), hash(setstruct2)
(0xe7d0f90913646f29, 0x3b31ce0af9245c64)
Run Code Online (Sandbox Code Playgroud)

现在注意以下几点:

julia> s = Set(["S"])
Set{String} with 1 element:
  "S"

julia> ss1 = SetStruct(s)
SetStruct(Set(["S"]))

julia> ss2 = SetStruct(s)
SetStruct(Set(["S"]))

julia> ss1 == ss2
true

julia> ss1 === ss2
true

julia> hash(ss1), hash(ss2)
(0x9127f7b72f753361, 0x9127f7b72f753361)
Run Code Online (Sandbox Code Playgroud)

这一次ss1ss2通过了所有测试,因为它们再次无法区分(如果您更改,ss1ss2更改同步,因为它们保持不变Set)。