【发布时间】:2012-07-19 10:12:11
【问题描述】:
1)string和string literal有什么区别
2) 一本书说'zero' at: 1 put: $h 会失败,因为文字是不可变的,但如果我这样做,'zero' copy at: 1 put: $h 会起作用,因为复制文字字符串会产生另一个不是文字的字符串。糊涂了!
【问题讨论】:
1)string和string literal有什么区别
2) 一本书说'zero' at: 1 put: $h 会失败,因为文字是不可变的,但如果我这样做,'zero' copy at: 1 put: $h 会起作用,因为复制文字字符串会产生另一个不是文字的字符串。糊涂了!
【问题讨论】:
假设你有一个方法回答一个文字字符串(字面意思是其内容按字面意思写在源代码中)
MyClass>>constantString
^'foo'
现在,如果这个文字字符串是可变的,你可以讨厌地执行这个 sn-p
MyClass new constantString at: 1 put: $b.
然后,MyClass 的每个实例都会对#constantString 回答“boo”。但是,您无法理解为什么,因为源代码仍然指示“foo”。恶心……
一些 Smalltalk 方言使这些文字字符串不可变,以避免这种意外的坏惊喜。有些没有虚拟机对不变性的支持,将全部责任交给用户。
【讨论】:
#at:put 的 StringLiteral 类?
| 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' 只是另一个对象。在 Squeak 和 Pharo 中,这些文字只是普通的 String 实例,因此您可以随意改变它们。
正如上面的 sn-p 所示,这可能会导致意想不到的结果,因为如果将第一行更改为 a := 'foo'. b := 'foo'.,您最终仍会得到相同的结果:Squeak 悄悄地分享该文字,而不是创建一个新的具有相同的值。
【讨论】:
这本书是错的。在吱吱声中,字符串不是不可变的。那是哪本书?
'zero' at: 1 put: $h; yourself. => '英雄'
'zero' copy at: 1 put: $h; yourself => '英雄'
字符是不可变的。如果他们不这样做会很有趣。
【讨论】: