Smalltalk - 是否可以通过方法将字符串添加到 String 实例?

Smalltalk - Is it possible to add a string to a String instance via a method?

Smalltalk - 是否可以通过方法将字符串添加到 String 实例?

基本上我想要的是:

renderThisOn: aString

aString append: 'whatever text I want'

本质上,我希望 String 实例(ByteString 等)的行为类似于 Seaside 中的 "html" 对象。我将它作为参数传递给多个方法,每个方法都向它添加一些信息。

逗号法:

|a|
a := 'abc'.
a,'def'

ctrl+p 得到 'abcdef'

从实用的角度来看,答案是否定的,无法更改字符串的大小。您可以修改字符串的字符:

a := 'abc'.
a at: 2 put: $x.
a = 'axc' "true"

因此,当您连接两个字符串时,您会得到第三个字符串,而其他两个保持不变

s := 'abc'.
t := 'def'.
u := s , t.
s = 'abc'. "true"
t = 'def'. "true"

话虽如此,实际上有一种方法可以增大(或缩小)字符串。这个想法是使用become:(或becomeForward:)。此消息将用对参数的引用替换对接收者的所有引用。在你的情况下:

s := 'abc'.
t := 'def'.
assoc := s -> 3 "referene to s"
s become: s , t.
s = 'abcdef'. "true"
assoc key == s "true"

我之所以以不能更改字符串的大小开始我的回答是因为在绝大多数情况下使用 become: 是过度的,推荐的做法是检查代码并消除需要修改对象的结构。

Smalltalk 中的字符串文字是不可变对象。

可能有不同的方式:

传递 WriteStream 实例

renderThisOn: aWriteStream
    aWriteStream nextPutAll: 'whatever text I want'

您可以围绕 String 创建自己的 class 包装器并传递其实例:

renderThisOn: aStringWrapper
    aStringWrapper append: 'whatever text I want'

流更可取,因为流比字符串连接更快

根据您的使用方式,绳架可以满足您的需求。最简单的可能是传递一个数组,其中第一个也是唯一一个元素是您要在不同方法中更改的字符串。数组不会改变,但唯一的元素会随着您在其中放置不同的字符串而改变。更复杂的是创建一个专门的字符串持有者 class,其中包含一个字段来保存变化的字符串。然后,您可以在该持有者上实现通用字符串方法,以重定向到当前的实际字符串。