こんにちは、鈴木です。
Scala やってみようかな、という方へのエントリです。
コードと実行結果を多めに載せましたので、ぜひお手元で実行しながら読み進めていただけたらと思います。
Scala のインストール
Scala の公式サイトから Scala をダウンロードしましょう。
現時点での安定版の最新バージョンは 2.9.2 です。
展開してパスを通すなどすれば準備完了です!
Hello Scala!
以下のコードは「Hello Scala!」と表示する Scala コードです。
1 |
println("Hello Scala!") |
以下のような特徴があります。
- println メソッドで標準出力に出力することができます。
- Java と同じく、文字列はダブルクォート(")で囲みます。
- Java と異なり、文末のセミコロン(;)は不要です。
Scala プログラムの実行
Scala のプログラムは、インタプリタとして実行することも、コンパイルして実行することもできます。
scala コマンドは Scala のインタプリタ、scalac コマンドは Scala のコンパイラです。
scala コマンドで対話的に実行する方法
scala コマンドを引数無しで実行すると、対話的にプログラムを入力・実行することができます。
いわゆる REPL(Read-Eval-Print Loop)です。
REPL では入力したプログラムがすぐに評価・実行・結果の印字が行われます。
手軽に実行結果を確認することができるので、非常に便利です。
1 2 3 4 5 6 7 |
$ scala Welcome to Scala version 2.9.2 (OpenJDK Server VM, Java 1.6.0_24). Type in expressions to have them evaluated. Type :help for more information. scala> println("Hello Scala!") Hello Scala! |
scala コマンドの -e オプションでプログラムを指定する方法
scala コマンドの -e オプションで Scala プログラムを指定することができます。
ワンライナー向けの実行方法と言えます。
Scala でワンライナーを書くことは少ないと思いますが、何かの拍子で使うかもしれません。
1 2 |
$ scala -e 'println("Hello Scala!")' Hello Scala! |
scala コマンドでファイルに保存したプログラムを実行する方法
事前に Scala プログラムをファイルに保存しておき、それを scala コマンドで実行することができます。
コンパイルは行われず、インタプリタとして実行されます。
まず、「Hello.scala」という名前のファイルを作成し、以下の内容を記述します。
1 |
println("Hello Scala!") |
そして、scala コマンドで実行します。
1 2 |
$ scala Hello.scala Hello Scala! |
scalac コマンドでコンパイルし、scala コマンドで実行する方法
まず、「Hello.scala」という名前のファイルを作成し、以下の内容を記述します。
1 2 3 4 5 |
object Hello { def main(args: Array[String]) = { println("Hello Scala!") } } |
次に、scalac コマンドで、作成した「Hello.scala」をコンパイルします。
1 |
$ scalac Hello.scala |
コンパイルに成功すると、「Hello$.class」と「Hello.class」が作成されます。
scala コマンドで実行します。
1 2 |
$ scala Hello Hello Scala! |
Scala のファイルは Java のクラスファイルなので、java コマンドで実行することもできます。その場合は Scala のライブラリをクラスパスに指定します。
1 2 |
$ java -cp $SCALA_HOME/lib/scala-library.jar:. Hello Hello Scala! |
コメント
単一行コメント
単一行コメントは // から始めます。行末までがコメントとして扱われます。
1 |
// 単一行コメント |
複数行コメント
複数行コメントは /* で開始し、*/ で終了します。
1 2 3 4 5 6 7 8 9 10 |
/* 複数行コメント */ /* 複数行コメント /* 複数行コメントはネストすることができます。 */ */ |
変数
宣言
変数は val または var で宣言します。Scala の持つ型推論により、変数の型を明示指定する必要はありません。
1 2 3 4 5 |
scala> val x = 1 x: Int = 1 scala> var y = 2 y: Int = 2 |
変数の型を明示的に指定することもできます。
1 2 |
scala> val z:Int = 3 z: Int = 3 |
再代入(mutable / immutable)
val で宣言した変数は再代入することができません。
1 2 3 4 |
scala> x = 10 <console>:8: error: reassignment to val x = 10 ^ |
var で宣言された変数には再代入することができます。
1 2 |
scala> y = 20 y: Int = 20 |
通常は val を使用し、再代入が必要な場合のみ var を使うと良いでしょう。
リテラル
リテラルの種類
リテラルには以下のような種類があります。
- 整数
- 不動小数点数
- 論理値
- 文字
- 文字列
- シンボル
- XML
整数
Int 型のリテラルは以下のように記述します。
1 2 3 4 5 6 7 8 9 10 |
// 10 進数表記 0 123 // 16 進数表記 0xff 0xFF // 8 進数表記 010 |
Long 型のリテラルは末尾に l または L を付加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 10 進数表記 0l 123L // 16 進数表記 (10 進数で 255) 0xffl 0xffL 0xFFl 0xFFL // 8 進数表記 (10 進数で 8) 010l 010L |
不動小数点数
Double 型のリテラルは以下のように記述します。
1 2 3 |
1.0 1.0d 1.0D |
Float 型のリテラルは以下のように記述します。
1 2 |
1.0f 1.0F |
不動小数点数は指数表記で記述することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 314 * 0.01 314e-2 // 1 * 0.01 1e-2 // 1 * 0.1 1e-1 // 1 * 1 1e0 // 1 * 10 1e1 // 1 * 100 1e2 |
論理値
Boolean 型のリテラルは true または false です。
1 2 3 4 5 |
// 真 true // 偽 false |
文字
Char 型のリテラルは以下のように記述します。
1 2 3 4 5 6 7 8 9 |
// 通常文字 'a' 'あ' // 特殊文字 '\n' // Unicode 表記 '\u0061' |
文字列
String 型のリテラルは以下のように記述します。
1 2 3 4 5 6 7 |
// 単一行文字列 "Hello Scala" "Scalable\nLanguage" // 複数行文字列 """Scalable Language""" |
シンボル
Symbol 型のリテラルは以下のように記述します。
1 2 |
'x 'name |
XML
XML リテラル(scala.xml.Elem 型のリテラル)は以下のように記述します。
1 2 3 4 |
<language> <name>Scala</name> <version>2.9.0</version> </language> |
XML リテラルには変数の値を埋め込むことができます。
1 2 3 4 5 6 7 8 9 10 11 12 |
scala> val name = "Scala" name: java.lang.String = Scala scala> <language> | <name>{name}</name> | <version>2.9.0</version> | </language> res0: scala.xml.Elem = <language> <name>Scala</name> <version>2.9.0</version> </language> |
コレクション
コレクションの種類
以下のコレクションについて解説します。
- Range (範囲)
- List (リスト)
- Array (配列)
- Tuple (タプル)
- Map (マップ)
- Option (オプション)
Range
Range は範囲を表します。
1 2 |
scala> 1 to 3 res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3) |
Range は遅延型のコレクションです。遅延型のコレクションに含まれる要素は、実際にアクセスされるまでインスタンス化されることはありません。
1 2 |
scala> (1 to 2147483647).take(3) res0: scala.collection.immutable.Range = Range(1, 2, 3) |
「(1 to 2147483647)」は 1 から 2147483647 までの範囲を表しますが、「(1 to 2147483647).take(3)」では先頭の 3 要素のみを取り出しています。1 から 2147483647 までの整数がメモリ上に乗ることはありません。
List
リストは以下のように生成します。
1 2 |
scala> List(1, 2, 3) res0: List[Int] = List(1, 2, 3) |
Array
配列は以下のように生成します。
1 2 |
scala> Array(1, 2, 3) res0: Array[Int] = Array(1, 2, 3) |
Tuple
タプルとは、データ型に関係なく、いくつかの値の組を表すデータ構造です。
1 2 |
scala> (1, 2, 3) res0: (Int, Int, Int) = (1,2,3) |
コレクションの操作
foreach
foreach を使用すると、コレクションの各要素に対して指定したメソッドを適用することができます。
1 2 3 4 5 6 7 8 9 10 11 |
scala> (1 to 10).foreach(println) 1 2 3 4 5 6 7 8 9 10 |
filter
filter はコレクションから特定の条件を満たす要素を抽出します。
1 2 3 4 5 6 |
scala> (1 to 10).filter(x => x % 2 == 0).foreach(println) 2 4 6 8 10 |
filterNot
filterNot はコレクションから特定の条件を満たす要素を除外します。
1 2 3 4 5 6 |
scala> (1 to 10).filterNot(x => x % 2 == 0).foreach(println) 1 3 5 7 9 |
map
map はコレクションの各要素に指定した関数を適用した結果を保持する新しいコレクションを生成します。
1 2 3 4 5 6 7 8 9 10 11 |
scala> (1 to 10).map(x => x * x).foreach(println) 1 4 9 16 25 36 49 64 81 100 |
foldLeft
foldLeft は畳み込み処理を行います。例えば、1 から 10 までの整数の合計は求めるには、以下のように記述します。
1 2 |
scala> println((1 to 10).foldLeft(0)((x, y) => x + y)) 55 |
Fizz-Buzz 問題
ScalaでFizz-Buzzを書くと次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
scala> (1 to 100).map(x => x match { case x if x % 15 == 0 => "FizzBuzz" case x if x % 5 == 0 => "Buzz" case x if x % 3 == 0 => "Fizz" case x => x }).foreach(println _) 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz ...(中略)... FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz |
Enjoy Scala!
駆け足でしたが、Scalaの雰囲気を感じていただけたのではないでしょうか。
それでは、Enjoy Scala!