string
1)和有什么区别string literal
2)一本书说'zero' at: 1 put: $h
会失败,因为文字是不可变的,但如果我确实'zero' copy at: 1 put: $h
有效,因为复制文字字符串会产生另一个不是文字的字符串。使困惑!
想象一下,您有一个方法来回答文字字符串(字面意思是其内容按字面意思写在源代码中)
MyClass>>constantString
^'foo'
现在,如果这个文字字符串是可变的,你可以讨厌地执行这个片段
MyClass new constantString at: 1 put: $b.
然后 MyClass 的每个实例都会对 #constantString 回答“嘘”。但是,您无法理解为什么,因为源代码仍然指示“foo”。讨厌...
一些 Smalltalk 方言使这些文字字符串不可变,以避免这种意外的坏惊喜。有些没有虚拟机对不变性的支持,并将全部责任交给用户。
| a b |
a := b := 'foo'.
a == b. "=> true, so the identical string"
a at: 1 put: $b.
b "=> 'boo'
所以在 Squeak 中,可能在 Pharo 中,字符串文字不是不可变的。
其他 Smalltalks 确实支持不可变性,因此这些Smalltalks 中的字符串文字可能确实是不可变的。
关于复制,也许您正在从其他语言中继承假设。'foo'
是一个字面量,因为有创建 a 的语法String
,但实际上,'foo'
它只是另一个对象。在 Squeak 和 Pharo 中,这些文字只是普通的String
实例,所以你可以自由地改变它们。
如上面的代码片段所示,这可能会导致意想不到的结果,因为如果您将第一行更改为a := 'foo'. b := 'foo'.
您仍然会得到相同的结果:Squeak 悄悄地共享该文字,而不是创建具有相同值的新文字。
书错了。在吱吱声中,字符串不是不可变的。那是哪本书?
'zero' at: 1 put: $h; yourself.
=> '英雄'
'zero' copy at: 1 put: $h; yourself
=> '英雄'
但是字符是不可变的。如果他们不是,那会很有趣。