将有序集合转换为文字数组

Converting Ordered Collection to Literal Array

我有一个有序集合,我想将其转换为文字数组。下面分别是有序的集合和想要的结果:

an OrderedCollection(1 2 3)
#(1 2 3)

实现此目标的最有效方法是什么?

消息 asArray 将创建 Array 来自 OrderedCollection:

    anOrderedCollection asArray

这可能就是您想要的。

但是,鉴于您说您想要一个 文字数组 ,您可能正在寻找字符串 '#(1 2 3)'。在那种情况下,我会使用:

    ^String streamContents: [:stream | aCollection asArray storeOn: stream]

其中 aCollection 是您的 OrderedCollection

如果您还不熟悉 streamContents:,这可能是学习它的好机会。它在这种情况下的作用相当于:

    stream := '' writeStream.
    aCollection asArray storeOn: stream.
    ^stream contents

在捕捉模式的意义上:

    stream := '' writeStream.
    <some code here>
    ^stream contents

这在 Smalltalk 中相当普遍。

更新

如果我们稍微澄清一下 Smalltalk 中的 文字数组 是什么意思,也许会有所帮助。考虑以下两种方法

method1
  ^Array with: 1 with: 2 with: 3

method2
  ^#(1 2 3)

两种方法都使用相同的数组进行响应,其中一个包含条目 123。但是,这两个实现是不同的。在 method1 中,数组是 动态创建的 (即在运行时)。在 method2 中,数组是 静态创建的 (即在编译时)。事实上,当您接受(并因此编译)method2 时,数组被创建并保存到方法中。 method1相反,没有数组,每次调用方法时都会创建结果。

因此,如果您动态生成 Smalltalk 代码,则只需要创建字符串 '#(1 2 3)'(即数组的文字表示)。

您不能将现有对象转换为文字数组。要获得文字数组,您必须在源代码中使用文字数组语法来编写它。

但是,我相信你只是误解了文字数组的意思,你实际上只是在寻找一个数组。

文字数组只是一个数组(在 Pharo 和 Squeak [1] 中)是在编译时创建的,也就是说,当您接受方法时。

要将有序集合转换为数组,您可以使用 asArray

检查

的结果
#(1 2 3).
(OrderedCollection with: 1 with: 2 with: 3) asArray.

你会发现两者是相等的。

[1]:请看这里的解释:

在 Pharo 5.0(测试版)中,您可以:

    | oc ary |
oc := OrderedCollection new: 5.
oc addAll: #( 1 2 3 4 5).
Transcript show: oc; cr.
ary := oc asArray.
Transcript show: ary; cr.

成绩单上的输出是:

an OrderedCollection(1 2 3 4 5)
#(1 2 3 4 5)

literalArray 编码是一种"poor man's"持久化编码来获得表示,它可以从可编译的文字数组中重构对象。 IE。一个文字数组,它通过使用 decodeAsLiteralArray 重建对象。

它不是通用机制,主要是为了在方法中存储 UI 规范而发明的(参见 UIBuilder)。

只有 类 的一小部分支持这种 encoding/decoding,我不确定 OrderedCollection 是否支持任何方言。 在我使用的那个 (ST/X) 中,它没有,我得到了一个 doesNotUnderstand。

但是,添加所需的 encoder/decoder 并使其成为可能会相对容易。

但是,正如我所说,它的预期用途是 UI 规范,而不是作为一般持久性(编译对象持久性)机制。所以我宁愿不推荐使用它。