对于集合(不可变)和字符串(可变),“===”的行为似乎不符合 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
,因为 set1
和 set2
是两个不可变对象相同的内容。 (或者 ismutable(set1)
应该 return true
?)
字符串是可变的,但是两个不同的对象是“===
”
string1 = String("test")
string2 = String("test")
ismutable(string1)
Returns true
string1 === string2
Returns true
,但根据文档应该 return false
因为 string1
和 string2
是两个不同的可变对象,因此它们在内存中的地址应该不同。 (或者 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
)。
我想我遗漏了一点,因为在我的测试中,“===”的行为似乎不符合文档。
文档指出 “首先比较 x 和 y 的类型。如果它们相同,则可变对象按内存中的地址进行比较,不可变对象(例如数字)按内容进行比较位级别.
我从这个定义中理解的是:
- 对于可变对象,两个不同的对象(即不同的内存地址)不应该是“
===
” - 对于不可变对象,当内容相同时,它们应该是“
===
”
然而:
集合是不可变的,但是两个内容相同的对象不是“===
”
set1 = Set(["S"])
set2 = Set(["S"])
ismutable(set1)
Returns false
set1 === set2
Returns false
,但根据文档应该 return true
,因为 set1
和 set2
是两个不可变对象相同的内容。 (或者 ismutable(set1)
应该 return true
?)
字符串是可变的,但是两个不同的对象是“===
”
string1 = String("test")
string2 = String("test")
ismutable(string1)
Returns true
string1 === string2
Returns true
,但根据文档应该 return false
因为 string1
和 string2
是两个不同的可变对象,因此它们在内存中的地址应该不同。 (或者 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
)。