Struct Julia中是否对结构进行递归检查?似乎不是
当检查Julia中关于“struct”对象的相等性时,有一种行为我不理解。 文档说明::“对于集合,Struct Julia中是否对结构进行递归检查?似乎不是,struct,julia,Struct,Julia,当检查Julia中关于“struct”对象的相等性时,有一种行为我不理解。 文档说明::“对于集合,==通常对所有内容进行递归调用,但也可以考虑其他属性(如数组的形状)。”。虽然对于structs来说,它似乎是强制转换为==或其他类型。 以下是一个简单的工作示例: 正如所料: string1 = String("S") string2 = String("S") string1 == string2 =>返回true 以及: =>返回true 但是!
==
通常对所有内容进行递归调用,但也可以考虑其他属性(如数组的形状)。”。虽然对于structs来说,它似乎是强制转换为==
或其他类型。
以下是一个简单的工作示例:
正如所料:
string1 = String("S")
string2 = String("S")
string1 == string2
=>返回true
以及:
=>返回true
但是!这就是我不明白的:
struct StringStruct
f::String
end
stringstruct1 = StringStruct("S")
stringstruct2 = StringStruct("S")
stringstruct1 == stringstruct2
=>返回true
然而:
struct SetStruct
f::Set{String}
end
setstruct1 = SetStruct(Set(["S"]))
setstruct2 = SetStruct(Set(["S"]))
setstruct1 == setstruct2
=>返回false
在我看来,
==
是在结构的元素上测试的
所以我的问题是:在结构上测试时,
==
的真实行为是什么?它是播放=
还是==
?如果它像文档中所述那样强制转换=
,我误解了什么呢?对于struct
s,默认情况下=
返回到=
,例如:
setstruct1 == setstruct2
与
setstruct1 === setstruct2
现在我们来看看==
的工作方式。其定义为:
确定x
和y
是否相同,即没有程序能够区分它们
(我省略了其余的定义,因为我相信第一句话建立了一个良好的心理模型)
现在很明显,stringstruct1
和stringstruct2
是不可区分的。它们是不可变的,并且包含在Julia中不可变的字符串。特别是它们有相同的散列值(这不是一个确定的测试,但在这里是一个很好的心智模型)
现在可以区分setstrict1
和setstruct2
。它们存储不同的集合,虽然在比较时这些集合包含相同的元素,但它们具有不同的存储位置(因此将来它们可能会不同——简言之——它们是可区分的)。请注意,这些结构具有不同的哈希值:
julia> hash(setstruct1), hash(setstruct2)
(0xe7d0f90913646f29, 0x3b31ce0af9245c64)
现在请注意以下事项:
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)
这次ss1
和ss2
通过了所有测试,因为它们同样无法区分(如果更改ss1
,则ss2
同步更改,因为它们保持相同的Set
).虽然Bogumil的回答解释了正在发生的事情,但让我展示如何将您期望的行为引入到代码中
只需添加以下行
abstract type Comparable end
import Base.==
==(a::T, b::T) where T <: Comparable =
getfield.(Ref(a),fieldnames(T)) == getfield.(Ref(b),fieldnames(T))
伟大的这是有用的、完整的和清晰的。塔尔斯!伟大的这对于比较结构很有用。谢谢
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)
abstract type Comparable end
import Base.==
==(a::T, b::T) where T <: Comparable =
getfield.(Ref(a),fieldnames(T)) == getfield.(Ref(b),fieldnames(T))
struct SetStruct <: Comparable
f::Set{String}
end
setstruct1 = SetStruct(Set(["S"]))
setstruct2 = SetStruct(Set(["S"]))
julia> setstruct1 == setstruct2
true