2

1) What is difference between string and string literal

2) a book says 'zero' at: 1 put: $h will fail because literals are immutable but if I do 'zero' copy at: 1 put: $h works because copying a literal string produces another string which is not a literal. Confused!

4

3 に答える 3

5

リテラル文字列に応答するメソッドがあるとします (リテラルとは、その内容がソース コードで文字通りに記述されていることを意味します)。

MyClass>>constantString
    ^'foo'

さて、このリテラル文字列が変更可能な場合、このスニペットを厄介に実行できます

MyClass new constantString at: 1 put: $b.

次に、MyClass のすべてのインスタンスが #constantString に対して「boo」と応答します。ただし、ソース コードにはまだ「foo」と表示されているため、その理由はわかりません。汚い...

いくつかの Smalltalk 方言は、このような偶発的な悪い驚きを避けるために、これらのリテラル文字列を不変にします。不変性に対する仮想マシンのサポートがなく、すべての責任をユーザーに任せているものもあります。

于 2012-07-19T21:07:37.323 に答える
1
| a b |
a := b := 'foo'.
a == b. "=> true, so the identical string"
a at: 1 put: $b.
b "=> 'boo'

したがって、Squeak では、そしておそらく Pharo では、文字列リテラルは不変ではありません。

他の Smalltalk は不変性をサポートしているので、おそらくこれらのSmalltalk の文字列リテラルは実際に不変です。

コピーに関しては、おそらく他の言語からの仮定を引き継いでいます。'foo'を作成するための構文があるという意味ではリテラルですがString、実際に'foo'は単なる別のオブジェクトです。Squeak と Pharo では、これらのリテラルは単なる通常のStringインスタンスであるため、自由に変更できます。

上記のスニペットが示すように、予期しない結果につながる可能性があります。最初の行を に変更しa := 'foo'. b := 'foo'.ても、同じ結果になるためです。Squeak は、同じ値で新しいリテラルを作成するのではなく、静かにそのリテラルを共有します。

于 2012-07-19T13:28:47.840 に答える
1

その本は間違っています。squeak では、文字列は不変ではありません。それはどの本ですか。

'zero' at: 1 put: $h; yourself.=>「ヒーロー」

'zero' copy at: 1 put: $h; yourself=>「ヒーロー」

ただし、文字は不変です。そうでなければ面白いでしょう。

于 2012-07-21T14:43:26.827 に答える