関数型
val functionCall = func() と書くと関数を呼び出してその戻り値を取得しますが、
val functionCall = ::func と書くと関数そのものを参照します。
ラムダ
構文形式を確認する

関数をデータ型として扱う
戻り値の型を指定しなければ、コンパイラは自動的に
Unitを戻り値とみなします。
Kotlinでは、すべての関数は何かを返す必要があります。戻り値を指定しない場合、コンパイラは自動的にUnit() : () -> /型/のように書くことで、関数の戻り値の型を明示的に指定したことになります。
さまざまな書き方の例:
fun main() {
val refFunction = ::sampleFunction
refFunction()
val refLambda = sampleLambda
refLambda()
f2()
createProcessor(name = "ProcessorA")(5)
}
fun sampleFunction(): () -> Unit {
println("sampleFunction called!")
return { println("Returned function from sampleFunction!") }
}
val sampleLambda = {
println("sampleLambda called (val lambda)!")
}
val f2: () -> Unit = fun() {
println("Anonymous function via lambda syntax")
}
// 引数で String を受け取り、「Int を受け取って Unit を返す関数」を返す
fun createProcessor(name: String): (Int) -> Unit {
return { count ->
println("$name は $count 個のタスクを処理しました")
}
}
// なぜこのように二重の括弧(createProcessor(...)(...))を使うのか?
// より複雑な関数呼び出しを実現するためです。
入れ子の面白い例
fun trickOrTreat(isTrick: Boolean, extraTreat: ((Int) -> String)?): () -> Unit {
// 実装省略
}
自然言語での説明
この関数は、isTrick という Boolean 引数と、関数を受け取ります。
渡される関数は Unit を返します(返される関数は引数をキャプチャしません)。
渡される関数は null 許容で、もし非 null であれば Int を受け取り String を返します。
スコープ外で it を使わない場合、明示的に引数名を指定する
fun main() {
// quarters -> で引数に名前を付けている
println(trickOrTreat(true) { quarters -> "$quarters quarters" })
println(trickOrTreat(false) { quarters -> "$quarters quarters" })
val quarters = 3
println("$quarters quarters")
}
// ラムダ内でも quarters という名前にする必要がある
val treatFunction = trickOrTreat(false) { quarters -> "$quarters candies" }
fun trickOrTreat(isTrick: Boolean, treatFunction: (quarters: Int) -> String): String {
return if (isTrick) "Trick!" else treatFunction(2)
}
通常は it を使って簡潔に書く:
fun main() {
println(trickOrTreat(true) { "$it quarters" })
println(trickOrTreat(false) { "$it quarters" })
}
val treatFunction = trickOrTreat(false) { "$it candies" }
fun trickOrTreat(isTrick: Boolean, treatFunction: (Int) -> String): String {
return if (isTrick) "Trick!" else treatFunction(2)
}
例えば、以下の coin は削除可能:
fun main() {
val coins: (Int) -> String = {
"$it quarters"
}
val treatFunction = trickOrTreat(false, { "$it quarters" })
val trickFunction = trickOrTreat(true, null)
treatFunction()
trickFunction()
}