9

在查看 Smalltalk 语法定义时,我注意到数组有一些不同的表示法:

#[] "ByteArray"
#() "Literal Array"
{}  "Array"
  • 为什么有不同的数组类型?在其他编程语言中,我知道只有一种独立于存储类型的数组。
  • 什么时候选择哪种?
  • 为什么文字数组和数组有不同的符号但相同的类?
4

2 回答 2

17

迈克尔的回答中有一些术语混乱,#()是文字数组,而{}不是。文字数组是由编译器创建的数组,可以包含任何其他文字值(包括其他文字数组),因此以下是有效的文字数组:

#(1 #blah nil ('hello' 3.14 true) $c [1 2 3])

另一方面 {} 只是运行时数组创建的语法糖,因此{ 1+2. #a. anObject}相当于:

(Array new: 3) at: 1 put: 1 + 2; at: 2 put: #a; at: 3 put: anObject; yourself
于 2013-01-27T16:47:11.557 回答
11

这是一个小演练:

首先,我们可以找出类型。结果对象的类:

  • #[] class结果是ByteArray
  • #() class结果是Array
  • {} class也导致Array

所以显然后两个产生数组,而第一个产生一个字节数组。ByteArrays 是您所期望的——固定大小的字节数组。

现在我们必须弄清楚#()和之间的区别{}。尝试评估#(a b c),结果是#(#a #b #c);但是,当您尝试评估时{a b c},它不起作用(因为a未定义)。工作版本将是{#a. #b. #c},这也会导致#(#a #b #c).

#()和之间的区别在于{},第一个采用空格分隔的符号名称列表。您也可以省略这些#标志。使用此表示法,您只能创建包含符号的数组。第二个版本是通用数组字面量。它接受任何表达式,用.(点)分隔。您甚至可以编写诸如{1+2. anyObject complexOperation}.

这可能会导致您始终使用该{}符号。但是,有一些事情要记住: 对象创建的时刻不同:虽然#()数组是在编译期间创建的,但{}数组是在执行期间创建的。#()因此,当您使用表达式运行代码时,它也将返回相同的数组,而{}只返回相等的数组(只要您使用相等的内容)。此外,AFAIK{}不一定是可移植的,因为它不是 ST-80 标准的一部分。

于 2013-01-27T13:00:45.333 回答