アンダーバー"_"
全然意味がわからなかったんだけど、なんかわかった。
Scalaのライブラリを読んでいると、関数への引数に "_" を使っているのが目につく。
どうも、"_" は、無名関数を作成するショートカットらしい。
例えばこんなの。
List("abc", "def", "ghi").map(_(1)) List("abc", "def", "ghi").map(_.length) List(1, 2, 3).filter(_ % 2 == 0)
こいつらは、ちゃんと書くと。
List("abc", "def", "ghi").map((x) => x(1)) List("abc", "def", "ghi").map((x) => x.length) List(1, 2, 3).filter((x) => x % 2 == 0)
になる。
上記は、引数が1つだけの例だけど、引数が複数の場合も使える。
List(1, 2, 3, 4, 5).reduceLeft[int](_ + _)
これは、
List(1, 2, 3, 4, 5).reduceLeft[int]((a, b) => a + b)
と同じ。
"_" が登場する順番と、引数の順番が一致していないと起こられるっぽい。
例えば、
class ClassA { def methodA = "METHOD A" } class ClassB { def methodB = "METHOD B" } def hoge(f:(ClassA, ClassB) => String) = f(new ClassA, new ClassB)
な感じで、ClassAクラス、ClassBクラス、hoge関数を用意する。
以下の呼び出しは、OK。
hoge(_.methodA + " " + _.methodB) // 結果: METHOD A METHOD B
最初の"_"には、ClassAが、最初の"_"には、ClassBが割り当てられる。
methodBと、methodAの呼び出しを逆にすると、いかのとおり、がっつり怒られる。
hoge(_.methodB + " " + _.methodA) <console>:6: error: value methodB is not a member of ClassA hoge(_.methodB + " " + _.methodA)
あと、"_" に対して型指定もできる。
(_: int) + (_: String).length
これは、こんな無名関数を書いたのと同じ。
(a: int, b: String) => a + b.length