Smalltalk数组类型

时间:2013-01-27 12:44:10

标签: arrays smalltalk squeak

在查看Smalltalk语法定义时,我注意到了一些不同的数组符号:

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

2 个答案:

答案 0 :(得分: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 等同于:

{{1}}

答案 1 :(得分:11)

这是一个小小的演练:

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

  • #[] class会产生ByteArray
  • #() class会产生Array
  • {} class也会产生Array

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

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

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

这可能会导致您始终使用{}表示法。但是,有一些事情要记住:对象创建的时刻不同:在编译期间创建#()数组时,{}数组在执行期间创建。因此,当您使用#()表达式运行代码时,它还将返回相同的数组,而{}仅返回相等的数组(只要你正在使用相同的内容)。另外,AFAIK {}不一定是便携式的,因为它不属于ST-80标准。