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