「Scalaスケーラブルプログラミング」8章

  • 理解
    • privateメソッド: 他のクラスの名前空間をメソッドと同様に,メソッド内に関数を定義することで,他のメソッドの名前空間を汚さない
      • そうすることで,関数内の変数を使えるというメリット(関数がより単純になる)もある
    • First-class functions: 変数のようにオブジェクトとして存在できる関数のこと
      • def functionName {} ではなく, var/val functionName = Input => Output
    • よく,関数の引数に関数を渡したくなる.例えば (x: Int) => println(x)をforeachに渡す.これを短縮したいという意図から以下のルールがある
      • 引数の型 (Int)を省略可能,さらにその時()も省略可能 : 入力した変数から推測できる (できない場合エラー)
      • 引数を _ により表すことが可能
        • 型が自明でないならば,(_: Int)のように書く
        • 複数回 _が使われると,違う変数が参照される e.g. f =(_: Int) + (_:Int) f(1, 2) = 3
          • 同じものを2回参照するように使うことはできない
        • 引数全体を _ として表すことも可能
          • foreachの引数のように,関数であることが明らかならば,_も省略可能 a.foreach(println)
    • 部分適用関数: もともとある関数の一部のみを引数とするように _ で書き換える
    • closure: 中で使われている未定義変数を外で定義している関数オブジェクト
      • 変数の値が変更されれば,closureが返す値も変化する
      • しかし,closureの中で外の変数を更新していくやり方は危険である (並列にしたら訳が分からなくなる)
      • closureを次々に生成するのがよい
        • def increase (x: Int) = x + more ではなく
        • def makeIncreaser (x: Int) = (x: Int) => x + more
    • 同じ型の引数が繰り返される場合, *を使う. def f (x: Int*) = ... はInt型の未定数(0-)の長さのArrayが引数
      • しかし,その場合にArray[Int]は渡せない arr: _* とすれば渡せる
    • 再帰関数はループの最後に書くことで最適化される,ただし2つの再帰関数が依存しているような複雑な例はだめ
  • わからなかった
    • 関数内の変数を使うと,記述は単純になるがテストが大変では? なので,関数内での更新はユーザ側でやらないようにする