ブロックを使う
ScalaByExample - Example 4.3 Conditional ExpressionsからScalaByExample - Example 4.5 Nested Functionsあたりのポイントまとめ。
if-else は値を返す
Scalaのif-else制御構文は値を返します。なので三項演算子的に使うことができるとのこと。
// if は値を返す。 println( if (true) "true!" else "false!" )
実行結果です。
true!
新しいなー、とか思ったけどそういえばRubyのifも一緒だったな。(←あんまし有効活用してない・・・。三項演算子派。)
$ ruby -e 'puts( if (true); "true!" else "false!" end)' true!
ブロックを使う
「{<処理...>}」でブロックを作成できます。
- Scalaのブロックはそれ自体が式で、
- 最後に実行された式を評価結果として返します。
- ブロック中には複数の式を書くことができます。
- 各式は「;」で分割されますが、以下の条件に合致しない場合、各行の末尾に自動で挿入されるため省略可能です。
- 問題となる行がビリオドのような単語や、式の最後として正しく無い中置演算子で終わる場合。
- 次の行が、式を開始出来ない様な単語で始まっている場合。
- 括弧 (...) か角括弧 [...] の内側にいる場合。
- 各式は「;」で分割されますが、以下の条件に合致しない場合、各行の末尾に自動で挿入されるため省略可能です。
- Scalaのブロックはスコープを持ちます。(いわゆるブロックスコープが採用されています)
- ブロック内で定義した変数や関数は、ブロックの内側からのみ参照できます。
- ブロック内にネスとしたブロックがある場合、外側のブロックで定義された変数などは内側のブロック内でも参照できます。
// Scalaのブロックは最後に実行された式の結果を返す式。 // 複数の式を追加できる。 println( { "a" // 式。 // 「;」で区切る必要があるが特定の場合を除き、 // 改行の前に自動挿入されるため、省略できる。 "b" "c" } ) // "c" // 一行にたくさん書きたいときは「;」を明示してね、ということ。 println( { "a" ; "b" ; "c" } ) // "c" // ブロックはスコープを持つ。 // ブロック内で定義した変数や関数はブロック内に限り参照できる。 { var x = 1 def y(i:int) = i*2 println( y(x) ) // "2" // ネストしたブロック内では外側で定義した関数や変数にアクセスできる。 { println( y(x) ) // "2" } } // ブロック外ではxやyは参照できない。以下はコンパイルエラー //println( y(x) )
ブロックの使い方例。関数内関数が作れます。
// ブロックの使い方例。 // ブロックを使って関数内関数が作れる。 def foo() = { // 関数内関数「hoge」 // hogeは関数foo内からのみ参照できる。 def hoge(i:int) = { i*2 } hoge( 3 ) } println( foo ) // 6
これ、JavaScriptでもできるな。
function foo() { function hoge(i) { return i*2; } return hoge( 3 ); }
ただ、こう書くと関数「foo」を実行するたびに「hoge」が生成されるのでもったいないんだけど。そのへんScalaではどうなってるんだろ。