目次
なにこれ
- コップ本にだいたい則ってScalaについてまとめたもの。
- Scala勉強会とかで使いたい。
- Scala処理系が入っている前提。
とりあえず触ってみる
- scalaコマンドを実行するとインタプリタが立ち上がる。
- 出力にはprintlnメソッドを使う。
- printlnメソッドはUnit型の唯一のメンバである()を返す→Javaのvoidに相当
変数の定義
- 上の定義の時にわざわざ型名(String)って書かなかった
型が明らかなときは型名を書かなくてもいい→型推論
- もちろん書いてもいい
- 変数の後ろにコロンを書いて型名
varとval
- 変数を定義するときにはvarとvalというキーワードが使える
- varは何度でも変更できる
- valは一度しか代入できない
- varはなるべく使わないほうがいい
- 変数の値をいつでも変えられるというのは強力だけど、同時にどこで変数の値が変わってしまったのかわかりにくくなる
- 極力valを使い、どうしてもパフォーマンスなどでvarのほうが良い時だけvarを使う。
関数定義
1 def 関数名(引数名:引数型, 引数名:引数型, ...):戻り値型 = 関数の式
- 具体的な例
- returnは省略できる
- 最後の式の結果が返される
- returnを省略して、かつ戻り値の型が明らかなら戻り値の方も省略できる
- 一行ならそもそも中括弧もいらない
1 def hello(name:String) = "Hello! " + name
単独で動くプログラムをつくってみる
- テンプレ
- 今はおまじないだと思いましょう
- argsはStringの配列になっていてmainメソッドの引数です。
- かけたらコンパイルします
scalac hoge.scala
- 実行します
scala hoge
- scalacじゃなくてfscを使うと便利です
- fscを使うと2回目以降コンパイルが速くなる
Scalaらしいループ
- argsの中身を順番に表示するプログラムを書いてみる
- こんなプログラムを書いてみよう
- scalaでは配列の添字は丸括弧
- インクリメントの演算子がないのでi += 1で我慢する
- 行末のセミコロンはいらない
- このプログラムは良くない
- varがあるから
- 配列にはforeachメソッドというのが用意されている
- 関数を引数にとってその関数を配列の要素に対して実行する
1 args.foreach((arg:String) => println(arg))
- argの型はStringなのはわかりきってるのでargの型名は省略できる
1 args.foreach(arg => println(arg))
配列
- 同じ型しか要素にとれない
- valで宣言しても要素の変更は自由
配列の生成
1 val hoge = Array[String](3)
配列への代入と参照
便利な配列の生成方法
1 val hoge = Array("Akari", "Kyoko", "Yui", "Chinatsu")
リスト
- 同じ型しか要素にとれない
- 要素の変更は(通常)不可能
- mutableなリストというのが特別に用意してあって、それを使えば良い。もちろん推奨はされない。
リストの生成
1 val hoge = List(2, 3, 5, 7)
リストの結合
リストの先頭に要素を追加
- これは実は下の糖衣構文になっている。つまりListの::というメソッドを呼び出してる
1 hoge.::(2)
- ::や:::のことをconsという
タプル
- 違う型の要素も持てる
- 要素の変更は不可能
- 言語の制約上22個しか要素が持てない
タプルを作る
1 val hoge = (1, "Kyoko", 2, "Akari")
タプルを使う
- タプルの要素番号はHaskellなどの慣習から1番スタートになっている
クラス
- Scalaはオブジェクト指向言語なのでクラスを持っている
- Javaとかと同じようにnewでクラスからオブジェクトを生成できる
1 val a = new Hoge()
- オブジェクトをval宣言の変数に代入しても、そのオブジェクトのフィールドがvar宣言されていれば再代入できる
メソッド
- メソッドの引数は勝手にvalで定義される
- 勝手に変えられないようにするため
- 戻り値がUnitのメソッドは=を省略できる。ただし=を省略すると中括弧を省略できない。
- メソッドをprivateにするには次のように記述する
1 private def hello() = "Hello, World!"
シングルトンオブジェクト
- Scalaは徹底したオブジェクト指向
- オブジェクトに属していないものの存在なんて許せない!!!!
- なのでstaticがありません
- そのかわりにシングルトンオブジェクトというのがある
シングルトンオブジェクトの定義
シングルトンオブジェクトの性質
- シングルトンオブジェクトはコードが実行されるときに自動的に生成される
- またあるスコープの中でひとつしかないことが保証される
- 多分後述
- 先ほど「単独で動くプログラムをつくってみる」の所でobjectうんたらと書いたのは、プログラム実行開始時にシングルトンオブジェクトを生成させてその中のmainメソッドを実行するというふうにScalaが仕組まれているから。
コンパニオンクラスとコンパニオンオブジェクト
- シングルトンオブジェクトと同じ名前のクラスを定義するとそれぞれコンパニオンオブジェクトとコンパニオンクラスと呼ばれるようになって、対で扱われるようになる。
- コンパニオンオブジェクトからはコンパニオンクラスにアクセスすることができる。
- コンパニオンオブジェクトはシングルトンオブジェクトなので、プログラム実行開始時に勝手に生成される。
- なのでstatic代わりに使える。
コンパニオンオブジェクトの例
基本型
- Scalaには次のような型がある
- 数値型
- Byte
- Int
- Long
- Short
- Double
- Float
- Char
- String
- Boolean
- 数値型
基本リテラル
整数リテラル
- Int, Long, Short, Byte型のリテラル。
- 10進、8進、16進表記可能。
浮動小数点リテラル
- 10進表記のみ。
- 指数表記もできる。
文字リテラル
- シングルクォートでUnicode文字を囲んだもの。
文字列リテラル
- 文字列をダブルクォートで囲ったもの。
- 改行するとそれもそのまま文字列として反映される
シンボルリテラル
- シンボルもやはり文字列を表すためのリテラル
- 次のように表記する
- 文字列リテラルとの違いは文字列へのシンボルリテラルであれば必ず同じオブジェクトへの参照になっているということ
Booleanリテラル
- TrueとFalseがある
演算子
- 演算子はメソッドです
- 演算子の種類はJavaに準ずるので適当にググってね
比較演算子について
- 1つだけ注意を要するのが比較演算子の==
- Javaではオブジェクトとしての等価性を判定するものだった
- Scalaでは内部的にJavaのequalsメソッドを呼び出しているので、==はオブジェクトの持っている値そのものの比較になる
演算子の優先順位について
- Scalaでは演算子の優先順位は演算子の名前で決まっている
- 演算子は特別な存在ではなく、ただのメソッドだから
- 例えば*メソッドは+メソッドよりも優先順位が高いとかいう決め方をしている
リッチラッパー
- ScalaではJavaの演算子に加えてもっと賢い演算子が使えるようになっている
- 例えば
- これはリッチラッパーというクラスによって用意されている。ふだん使うぶんにはリッチラッパーという存在を意識せずにそのまま使うことが出来る。