Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Kotlin辞典

高階関数

Kotlinでは関数を引数として受け取ったり、戻り値として返したりする「高階関数」が使えます。関数型『(T) -> R』で関数の型を表し、『::』で関数参照を取得できます。

構文
// 関数型を引数として受け取る高階関数
fun apply(x: Int, f: (Int) -> Int): Int = f(x)

// 関数を戻り値として返す
fun makeAdder(n: Int): (Int) -> Int = { x -> x + n }

// 関数参照(:: を使います)
fun double(x: Int) = x * 2
val list = listOf(1, 2, 3)
list.map(::double)   // [2, 4, 6]

// 複数の関数型
fun combine(a: Int, b: Int, op: (Int, Int) -> Int): Int = op(a, b)

// 戻り値がない関数型
fun doFor(n: Int, action: (Int) -> Unit) {
    for (i in 1..n) action(i)
}
構文一覧
記法概要
(T) -> R引数 T を受け取り R を返す関数型です。
(T, U) -> R複数引数の関数型です。
() -> Unit引数なし・戻り値なしの関数型です。
::関数名トップレベル関数の参照を取得します。
型名::メソッド名クラスメソッドの参照を取得します。
インスタンス::メソッド名特定のインスタンスのメソッド参照を取得します。
サンプルコード
// 関数型を引数として受け取ります。
fun applyTwice(x: Int, f: (Int) -> Int): Int = f(f(x))

// 関数を返す高階関数(クロージャ)
fun makeMultiplier(factor: Int): (Int) -> Int = { x -> x * factor }

// コレクション操作(関数型の典型例)
fun transform(list: List<Int>, op: (Int) -> Int): List<Int> = list.map(op)

// 関数参照を使う例
fun isEven(n: Int) = n % 2 == 0
fun square(n: Int) = n * n

fun main() {
    // 高階関数に lambda を渡します。
    println(applyTwice(3) { it + 10 })  // 23 (3+10+10)
    println(applyTwice(2) { it * 3 })   // 18 (2*3*3)

    // 関数を返して使います。
    val triple = makeMultiplier(3)
    val quintuple = makeMultiplier(5)
    println(triple(7))      // 21
    println(quintuple(4))   // 20

    // 関数参照(:: を使います)
    val numbers = listOf(1, 2, 3, 4, 5, 6)
    println(numbers.filter(::isEven))   // [2, 4, 6]
    println(numbers.map(::square))      // [1, 4, 9, 16, 25, 36]

    // 関数を組み合わせます。
    val result = transform(listOf(1, 2, 3, 4), ::square)
    println(result)  // [1, 4, 9, 16]

    // メソッド参照
    val strings = listOf("hello", "world", "kotlin")
    println(strings.map(String::uppercase))       // [HELLO, WORLD, KOTLIN]
    println(strings.map(String::length))          // [5, 5, 6]
    println(strings.sortedBy(String::length))     // [hello, world, kotlin]

    // 関数型の変数
    val ops: Map<String, (Int, Int) -> Int> = mapOf(
        "add" to { a, b -> a + b },
        "mul" to { a, b -> a * b }
    )
    println(ops["add"]!!(3, 4))  // 7
    println(ops["mul"]!!(3, 4))  // 12
}
概要

高階関数はKotlinのコレクション操作(『map()』『filter()』『fold()』など)の基盤となっています。『(T) -> R』という関数型を引数に取ることで、処理の内容を呼び出し側が決められる柔軟なAPIが設計できます。

関数参照(『::』)はラムダ式の代わりに既存の関数をそのまま渡す際に使います。『String::uppercase』のように型名::メソッド名の形で使うと、コレクション操作のコードが簡潔になります。

ラムダ式の構文はラムダ式を、拡張関数については拡張関数を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。