对于集合(不可变)和字符串(可变),“===”的行为似乎不符合 Julia 中的文档(至少 v1.5)

For Sets (immutable) and Strings (mutable), the behavior of "===" doesn't seem to comply to the documentation in Julia (v1.5 at least)

我想我遗漏了一点,因为在我的测试中,“===”的行为似乎不符合文档。

文档指出 “首先比较 x 和 y 的类型。如果它们相同,则可变对象按内存中的地址进行比较,不可变对象(例如数字)按内容进行比较位级别.

我从这个定义中理解的是:

然而:

集合是不可变的,但是两个内容相同的对象不是“===

set1 = Set(["S"])
set2 = Set(["S"])
ismutable(set1) 

Returns false

set1 === set2 

Returns false,但根据文档应该 return true,因为 set1set2 是两个不可变对象相同的内容。 (或者 ismutable(set1) 应该 return true?)

字符串是可变的,但是两个不同的对象是“===

string1 = String("test")
string2 = String("test")
ismutable(string1) 

Returns true

string1 === string2 

Returns true,但根据文档应该 return false 因为 string1string2 是两个不同的可变对象,因此它们在内存中的地址应该不同。 (或者 ismutable(string1) 应该 return false?)


我漏掉了什么?

这些情况很棘手,我同意这不直观。 Set 比较容易解释。

Set 定义为:

struct Set{T} <: AbstractSet{T}
    dict::Dict{T,Nothing}

    Set{T}() where {T} = new(Dict{T,Nothing}())
    Set{T}(s::Set{T}) where {T} = new(Dict{T,Nothing}(s.dict))
end

所以你可以看到虽然它是一个不可变的struct它的字段是一个可变的对象dict。所以dict字段的比较使用的是内存地址,都是一致的

但我同意令人困惑的是 Set 是不可变的,而 Dict 是可变的;然而,这里的一切都是一致的。


String 情况更复杂。它们被定义为不可变的,参见 here:

As in Java, strings are immutable: the value of an AbstractString object cannot be changed. To construct a different string value, you construct a new string from parts of other strings.

但它们在 Julia Base 中以非标准方式实现以提高性能。

因此大多数函数都遵循尊重不变性的规则(特别是===)。我认为字符串的 ismutable 应该更改其文档字符串或 return false (我个人的意见是它应该 return false)。