[scala][java][tutorial] Scala本を読む 8

「関数とクロージャー」

  • 8.1 導入
  • 8.2 ローカル関数

関数を関数内にスコープ内だけに有効な関数として定義できる
外側のスコープの関数のパラメータにアクセスできる。

  • 8.3 一人前の存在としての関数

"scalaにはfitst class functionsが用意されている"
⇒関数にファーストクラスオブジェクトと同じ性質を持たせられるということらしい。
ファーストクラスオブジェクト

    1. オブジェクトに名前がつけられる
    2. 引数として関数や手続きに渡すことができる
    3. 返り値にすることができる
    4. データ構造に含めることができる

"関数リテラルは実行時にインスタンス化すると値としての関数(function values)になる。"
クラスとオブジェクトの関係ににている。

パラメータの型の省略

numbers.filter((x: Int) => x > 0)
↓
numbers.filter((x) => x > 0)

"=>"は、左辺で受け取った引数を右辺で処理する関数を返す記法

numbers.filter(_ => > 0)
一回しか使わない場合は場所がわかる
  • 8.6 部分化された関数

これちょっと不思議

def sum(a: Int, b: Int, c:Int) = a+b+c
val a = sum _
a(1,2,3)
⇒ 6

アンスコを使うと、引数が部分的に適用(引数を渡して関数を実行すること)された関数が生成される

val b = sum(1, _: Int, 3)
b(2)
⇒ 6

内部でclass x{ def apply(_: Int){ sum(1, _, 3) }
みたいなクラスができているらしい

関数内で関数外のパラメータ(自由変数)を利用できる。
実行時にパラメータの実体を取得する必要がある⇒取得したものを束縛変数という(のか?)。

  • 8.8 連続パラメータ

Java5で追加されたやつみたい。

def echo(args: String*) 〜

処理の最後に自身を呼び出す関数。
コンパイラが最適化を行い、パラメータのみ更新して関数の戦闘にジャンプするようにしてくれる
⇒手続きの繰り返しとほとんど同じ実行速度となる
ただし再帰呼び出しにifなどが入ったりすると最適化されない。