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

问题描述

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

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

我从这个定义中了解到:

然而 :

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

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

退货false

set1 === set2 

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

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

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

退货true

string1 === string2 

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


我错过了什么?

标签: juliaimmutabilityequalitymutable

解决方案


这些情况很棘手,我同意这不直观。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情况比较复杂。它们被定义为不可变的,请参见此处

与 Java 一样,字符串是不可变的:AbstractString对象的值不能更改。要构造不同的字符串值,您可以从其他字符串的一部分构造一个新字符串。

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

因此,大多数函数都遵循尊重不变性的规则(特别是===)。我认为ismutablefor string 应该更改其 docstring 或 return false(我个人认为它应该 return false)。


推荐阅读