Akata Works

東京エンジニア。主にRuby,Go,たまにAWSとiOS。ゲーム音楽が好きです。連絡はTwitterかakata.onen@gmail.comまで

ScalaのArrayとApplyについて調べた

初、Scalaの記事です。

Scalaは言語仕様にオマジナイ的なものが少なくて、
勉強していて「なるほど、ここはこうなってんだ〜〜」て思うことが多いです。

さて、そんなScalaの配列ですが、定義方法だけでも結構あります。

val num: Array[Int] = new Array[Int](5);    // 型と要素数で定義
val num             = new Array[Int](5);    // 型推論
val num: Array[Int] = new Array(5);         // 型推論
val num             = new Array(5);         // Array[Nothing]
val num: Array[Int] = new Array[Double](5); // error: type mismatch;

上記はコンストラクタを用いた初期化です。

型と要素数をきっちり定義してもよし、型推論に身を任せてもよしです。
ちなみにブラケットはジェネリックです。
C#あがりの自分にとってはなつかしいものです(-_- )シミジミ


またクラスやオブジェクトにはApplyメソッドという特別なメソッドを定義することができ、定義されていればクラス名(オブジェクト名)のみで呼び出せます。

ArrayオブジェクトではArrayクラスのコンストラクタを呼び出すように実装されているので、 インスタンスの生成は以下のように記述することもできます。

val num: Array[Int] = Array[Int](1, 2, 3, 4, 5);    // 型と初期値で定義
val num             = Array[Int](1, 2, 3, 4, 5);    // 型推論
val num: Array[Int] = Array(1, 2, 3, 4, 5);         // 型推論
val num             = Array(1, 2, 3, 4, 5);         // Array[Int]
val num: Array[Int] = Array[Double](1, 2, 3, 4, 5); // error: type mismatch

Applyメソッドあなどれん・・

こんなかんじでオブジェクトをファクトリーにして同名クラスのインスタンスを生成させていることが多いです。
ちなみに、オブジェクト名とクラス名が同じものをコンパニオンオブジェクトといいます。

また、Applyクラスでは要素の取得・代入するように実装されているので、 要素の取得・代入は以下のように記述することができます。

val num = Array(1, 2, 3, 4, 5);
num(0)       // 1
num.apply(0) // 1
num          // 1, 2, 3, 4, 5
num(0) = 6
num.update(1, 7)
num          // 6, 7, 3, 4, 5

引数がふたつのときはUpdateメソッドを呼び出すように実装されています(こっちはオーバーロード)

うーん、Scalaはおもしろいですねー^_^

補足

実際のコードはこんなかんじです。

Arrayオブジェクト

def apply[A: ClassManifest](xs: A*): Array[A] = {
  val array = new Array[A](xs.length)
  var i = 0
  for (x <- xs.iterator) { array(i) = x; i += 1 }
  array
}