インストール
Windowsの場合、http://www.scala-lang.org/download/ からインストーラをダウンロードする。
Macの場合、brew install scala
。
※事前にJREのインストールが必要。
Scalaの特徴
- オブジェクト指向と関数型言語の特徴を併せ持つ静的型付け言語。
- JVM上で動作し、JavaのAPIやライブラリが使える。
- Javaより簡潔に書ける。
- Javaより強力な型推論。
- スクリプトが書ける。
- 演算子や制御構文を拡張できる。
Hello World
REPLでHello World
ScalaにはREPL(対話型インタープリター)が付属していて、コマンドラインから文を1行ずつ入力して実行する事ができる。
コマンドプロンプトからscala
コマンドを引数なしで実行するとREPLが起動する。
$ scala
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> println("Hello Scala")
Hello Scala
scala> :q
$
ScalaスクリプトでHello World
Scalaではスクリプトを作成する事ができる。
Scalaスクリプトファイルではクラスを定義せずにトップレベルから命令を書く。(クラスや関数を定義して使用する事も可能)
println("Hello " + args(0))
実行はscala
コマンドの第1引数でスクリプトファイル名を指定する。第2引数以降はスクリプトに渡す引数になる。
$ scala HelloScript.scala Scalaスクリプト
Hello Scalaスクリプト
$
ScalaアプリケーションでHello World
アプリを作成するにはmainメソッドを持つシングルトンオブジェクトを作成する。
object HelloApp {
def main(args: Array[String]): Unit = {
println("Hello " + args(0))
}
}
Appトレイトを使用すると以下のように短く書けるようになる。
object HelloApp extends App {
println("Hello " + args(0))
}
実行はscalac
コマンドでソースファイルをコンパイルしてからscala
コマンドで行う。
$ scalac HelloApp.scala && scala HelloApp Scalaアプリ
Hello Scalaアプリ
$
Scalaのソースファイルの基本
- 拡張子は
.scala
。 - インデントはスペース2桁を推奨。
- トップレベルに定義するクラス名はファイル名と同じでなくても良い。
- トップレベルにpublicなクラスを複数定義できる。
- 文末のセミコロンは省略できる。
- アクセス修飾子を省略した時のデフォルトは公開。
- Scalaでは以下のパッケージとオブジェクトのメンバーを暗黙でインポートする。
基本型
- Byte
- Short
- Int
- Long
- Char
- String
- Float
- Double
- Boolean
- Array
Javaではプリミティブ型とラッパークラスがあり、プリミティブ型はオブジェクトではないので特別な扱いが必要だったが、Scalaでは全てがオブジェクトとして扱える。
整数リテラルもIntクラスのオブジェクトなので以下のようにメソッドを呼び出す事もできる。
123.toString()
配列も特別な型ではなく、Javaのコレクションクラスのように型パラメータを持つArrayクラスのオブジェクトになる。
変数の定義
初期化後に再代入できない変数はval
、再代入可能な変数にはvar
を使用する。
型推論されるので型の指定は省略可能。
val a = 1
val b: Int = 2
// b = 2 //コンパイルエラー。val変数への再代入は不可。
var c = 3
var d: Int = 4
c = 5
d = 6
// c = "a"; //コンパイルエラー。型が違う値は再代入できない。
関数の定義
関数の定義はdef
を使う。
class内またはobject内に定義した関数はメンバーメソッドになる。
スクリプトではクラスの外側でも関数を定義できる。
class Class1 {
def method1() {} // クラスClass1のメンバーメソッド
}
def func1() {} // クラスとは独立した関数
戻り値を返す関数
2つの整数値を受け取って整数値を返す関数は以下のようになる。
def sum(a: Int, b: Int): Int = { return a + b }
returnを書かなくても最後の式が戻り値になる。
def sum(a: Int, b: Int): Int = { a + b }
式が1つの時は{}を省略できる。
def sum(a: Int, b: Int): Int = a + b
戻り値の型は型推論で省略できる。
def sum(a: Int, b: Int) = a + b
引数の型は省略できない。
戻り値がない関数
戻り値がない関数は戻り値の型をUnit
にする。
def printText(text: String):Unit = println(text)
最後の式の結果がUnit
なら戻り値の型を省略できる。
def printText(text: String) = println(text) //printlnの戻り値はUnitなのでこの関数の戻り値の型もUnitになる
関数本体の前に=
を付けずに関数本体を{}で囲ってある場合は、最後の式が値を返してもこの関数の戻り値はUnit
になる。
def func1(a: Int, b: Int) { sum(1, 2) } //戻り値はUnitになる
引数のデフォルト値
引数にデフォルト値を定義すると呼び出し時に省略可能になる。
def func1(a: Int = 0) = a + 1
println(func1(1)) // => 2
println(func1()) // => 1
関数リテラル
Java8でいうラムダ式。
関数を関数の引数に渡したり変数に代入する時に使用する。
val func1 = (a: Int, b: Int) => { a + b } : Int
戻り値の型を省略したり{}
を省略できるのは関数定義と一緒。
val func1 = (a: Int, b: Int) => a + b
クラスの定義
クラスHoge
に非公開フィールドa
と公開メソッドgetA
を定義するには以下のようにする。
class Hoge {
private val a = 3
def getA() = a
}
クラス本体の{}
は省略できる。
class Hoge
基本コンストラクタ
クラスのブロック内に書いたコードが基本コンストラクタの処理になる。
class Hoge {
println("created.")
}
new Hoge() // => created.
以下のように書くと、基本コンストラクタで引数を受け取ってクラスのフィールドに設定してくれる。
class Hoge(private val a: Int)
上記はJavaで以下のように書いたのと同じ意味。
public class Hoge {
private int a;
public Hoge(int a) {
this.a = a;
}
}
アクセス修飾子とvar/val
を省略するとprivate val
になる。
class Hoge(a: Int)
基本コンストラクタのアクセス修飾子はクラス名と引数の間に指定する。
class Hoge private (a: Int)
補助コンストラクタ
基本コンストラクタ以外にコンストラクタを定義する時はthis
という名前のメソッドを使う。
補助コンストラクタでは最初に他のコンストラクタを呼ばなくてはならない。
class Hoge(a: Int) {
def this(a: Int, b: Int) { this(a + b) }
}
親クラスのコンストラクタの呼び出し
class Parent(a: Int)
class Child extends Parent(1)
class Child(a: Int) extends Parent(a * 2)
override
親クラスのメソッドをオーバーライドする時はoverride
修飾子をつける。(アノテーションではない)
class Hoge {
def f() = println("hoge")
}
class Meke {
override def f() = println("meke")
}
シングルトンオブジェクト
Javaではクラスに静的(static)メンバーを持つことができるが、Scalaではできない。
代わりにScalaではシングルトンオブジェクトを使用してそこにメンバーを定義する。
シングルトンオブジェクトの定義はobject
キーワードを使用する。
object Hoge {
def method1() {}
}
使用する箇所ではJavaで静的メンバーを呼ぶのと同じ形式で呼び出す。
Hoge.method1()
コンパニオンオブジェクト
クラスと同じ名前のシングルトンオブジェクトを定義した場合はコンパニオンオブジェクトと呼ばれる。
コンパニオンオブジェクトはクラスと同じソースファイルに定義しなければならない。
class Hoge {
}
object Hoge {
}
スタンドアロンオブジェクト
コンパニオンオブジェクトではないシングルトンオブジェクトは、スタンドアロンオブジェクトと呼ばれる。
パッケージ
Scalaでは1ファイルに複数パッケージを書いたり、ネストしたりできる。
import package1
class Class1
import package1 {
class Class1
}
import package2 {
import package3 {
class Class2
class Object3
}
}
インポート
import package1.Class1
import package2.package3._
import package2.package3.{Class2, Object3}
import package2.package3.Object3._
import package2.package3
new package3.Class2()
配列
サイズが3のInt配列を作成する。
val a = new Array[Int](3)
初期値を指定して配列を作成する。
val a = Array(1, 2, 3)
if式
Scalaのif
は式なので値を返せる。
val a = if (b == 1) 1 else 2
ちょっと長くなったのでまとめ
だらだらと書いてたら長くなってしまったので終わりにする。
他にも以下は基本として覚えておかなければならないけど、またの機会にする。
- trait
- for式
- コレクション