Smalltalk の構文定義を見ていると、配列の表記がいくつか異なることに気付きました。
#[] "ByteArray"
#() "Literal Array"
{} "Array"
- 異なる配列タイプがあるのはなぜですか? 他のプログラミング言語では、格納された型に依存しない配列は 1 種類しかないことを知っています。
- どの種類をいつ選ぶ?
- リテラル配列と配列の表記が異なるのに同じクラスなのはなぜですか?
マイケルの答えに#()
は用語の混乱が少しありますが、リテラル配列{}
ではありません。リテラル配列はコンパイラによって作成されたものであり、他のリテラル値 (他のリテラル配列を含む) を含むことができるため、以下は有効なリテラル配列です。
#(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
ここに少しウォークスルーがあります:
まず、それぞれの型を見つけることができます。結果のオブジェクトのクラス:
#[] class
結果はByteArray
#() class
結果はArray
{} class
また、Array
したがって、後者の 2 つは配列を生成し、最初の 2 つは ByteArray を生成するようです。ByteArrays はあなたが期待するもので、固定サイズのバイト配列です。
ここで、 と の違いを理解する必要が#()
あり{}
ます。を評価#(a b c)
してみてください#(#a #b #c)
。ただし、 を評価しようとして{a b c}
も機能しません (a
が定義されていないため)。作業バージョンは になりますが{#a. #b. #c}
、これも になり#(#a #b #c)
ます。
#()
との違い{}
は、最初のものがスペースで区切られたシンボル名のリストを取ることです。#
記号を省略することもできます。この表記を使用すると、シンボルを含む配列のみを作成できます。2 番目のバージョンは、一般的な配列リテラルです。.
(ドット)で区切られた任意の式を取ります。のように書くこともできます{1+2. anyObject complexOperation}
。
これにより、常に{}
表記法を使用することになります。ただし、注意すべき点がいくつかあります。 オブジェクト作成の時点が異なります。配列は#()
コンパイル中に作成されますが、{}
配列は実行中に作成されます。#()
したがって、式を使用してコードを実行すると、同じ配列も返されますが、等しい{}
配列のみが返されます (等しい内容を使用している場合)。また、ST-80標準の一部ではないため、AFAIKは必ずしも移植可能ではありません。{}