Struct Julia中是否对结构进行递归检查?似乎不是

Struct Julia中是否对结构进行递归检查?似乎不是,struct,julia,Struct,Julia,当检查Julia中关于“struct”对象的相等性时,有一种行为我不理解。 文档说明::“对于集合,==通常对所有内容进行递归调用,但也可以考虑其他属性(如数组的形状)。”。虽然对于structs来说,它似乎是强制转换为==或其他类型。 以下是一个简单的工作示例: 正如所料: string1 = String("S") string2 = String("S") string1 == string2 =>返回true 以及: =>返回true 但是!

当检查Julia中关于“struct”对象的相等性时,有一种行为我不理解。 文档说明::“对于集合,
==
通常对所有内容进行递归调用,但也可以考虑其他属性(如数组的形状)。”。虽然对于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