在 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)
=> 返回假
对我来说,它看起来像是===对结构的元素进行了测试。
所以我的问题是:==在结构上测试时的真实行为是什么?它是投射==还是===?如果它==按照文档说明进行转换,我误解的重点是什么?
对于structs 默认情况==下回退到===,因此例如:
setstruct1 == setstruct2
Run Code Online (Sandbox Code Playgroud)
是相同的
setstruct1 === setstruct2
Run Code Online (Sandbox Code Playgroud)
所以现在我们深入了解===工作原理。它被定义为:
确定
x和y是否相同,因为没有程序可以区分它们。
(我省略了定义的其余部分,因为我相信这第一句话建立了一个很好的心理模型)。
现在清楚stringstruct1和stringstruct2不可区分。它们是不可变的,并且包含在 Julia 中不可变的字符串。特别是它们具有相同的hash值(这不是一个明确的测试,但在这里是一个很好的心理模型)。
julia> hash(stringstruct1), hash(stringstruct2)
(0x9e0bef39ad32ce56, 0x9e0bef39ad32ce56)
Run Code Online (Sandbox Code Playgroud)
现在setstrict1和setstruct2是有区别的。它们存储不同的集合,虽然在比较时这些集合包含相同的元素,但它们具有不同的存储位置(因此将来它们可以不同 - 简而言之 - 它们是可区分的)。请注意,这些结构特别具有不同的哈希值:
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)
这一次ss1并ss2通过了所有测试,因为它们再次无法区分(如果您更改,ss1则ss2更改同步,因为它们保持不变Set)。