Akasaka.scala 31に参加してきた
今日はAkasaka.scala 31に参加してきました。その時のメモと、後で調べようと思っていたことを書きます。(Akasaka.scalaについてはこちらを見て下さい)
今日の内容はScalaの言語仕様読書会(第4章)と、Play2.0のハンズオンでした。
Scala言語仕様 2.8 リーディング
まず、言語仕様読書会ですが、今回は「基本的な定義と宣言」でした。毎回@seratchさんが前もって予習した内容を記事にして頂いているので、そちらとScala2.8の言語仕様日本語訳を中心に読み進めました。「値の定義でパターンをとる」が面白かったです。こんなのができます。
val Some(x) = Option("foo") println(x) // foo
上記の最初の代入は下記のように展開されるようです。(コンパイラが頑張る)
val x = Option("foo") match { case Some(x) => x }
でも、この例、使うことあるんだろうか。。Optionという事はNoneの可能性があるんだし、実際こうするとMatchErrorが飛んでくる。。
val n: Option[String] = None val Some(x) = n // scala.MatchError: None (of class scala.None$)
この仕様を使ってTupleを返すメソッドの結果を、複数同時に束縛できるのは便利です。
def search() = (List("abc", "defg", "hi"), 233) val (list, numFound) = search()
final valというのもありました。valが再代入不可なのに何をfinalにする必要があるのだろう、と思っていましたが、finalをつけると定数式として扱われ、Scalaコンパイラが定数へ評価できるそうです。・・・よく分からなかったのでコード書いて試してみました。final valを使ったコードをいったんscalacでコンパイルし、それをさらにJava Decompilerで逆コンパイルし、Javaでどのように表現されるかを確認しています。
元のscalaコードです。
上記コードをscalacでコンパイルしたものを逆コンパイルしたコードです。
変数v1にはfvが代入されているのではなく、直接"abcd"が代入されています。v2にはv1(実際にはv1()メソッド)の結果が代入されています。v3〜v5は比較用の非finalなvalのコードです。よく分からないのがfvの変数で、finalなのに代入されていません。これをJavaのコードにするとコンパイルエラーになるので、恐らくnullが入っています。(※Scalaではfvと書いても自動生成されたfv()が呼ばれるので、通常は問題になりません。)ホントかどうか試してみました。
nullになってますね。