Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
単一式関数 / ローカル関数
Kotlinでは関数が1つの式で完結する場合、中括弧と『return』を省略した「単一式関数」として書けます。また関数の中に関数を定義する「ローカル関数」で処理をスコープ内にカプセル化できます。
構文
// 通常の関数
fun double(x: Int): Int {
return x * 2
}
// 単一式関数(= を使って簡潔に書けます)
fun double(x: Int): Int = x * 2
// 型推論で戻り値型も省略できます。
fun double(x: Int) = x * 2
// ローカル関数(関数の中に関数を定義します)
fun process(numbers: List<Int>): List<Int> {
fun validate(n: Int): Boolean = n > 0 // ローカル関数
return numbers.filter { validate(it) }
}
構文一覧
| 構文 | 概要 |
|---|---|
| fun name(p) = 式 | 単一式関数です。= の右辺がそのまま戻り値になります。 |
| 戻り値型の省略 | 式から型が推論できる場合は戻り値型を省略できます。 |
| ローカル関数 | 関数の内部で定義する関数です。外側のスコープの変数にアクセスできます。 |
| ネスト関数 | ローカル関数内でさらにローカル関数を定義できます。 |
サンプルコード
// 単一式関数の例
fun square(n: Int) = n * n
fun greet(name: String) = "Hello, $name!"
fun isEven(n: Int) = n % 2 == 0
fun max(a: Int, b: Int) = if (a > b) a else b
// ローカル関数の例
fun findDuplicates(numbers: List<Int>): List<Int> {
// ローカル関数 — 外側の変数 numbers にアクセスできます。
fun hasDuplicate(n: Int): Boolean =
numbers.count { it == n } > 1
return numbers.filter { hasDuplicate(it) }.distinct()
}
// ローカル関数で再帰を使う例
fun factorial(n: Int): Long {
fun calc(x: Int, acc: Long): Long = // 末尾再帰用ローカル関数
if (x <= 1) acc else calc(x - 1, acc * x)
return calc(n, 1L)
}
fun main() {
// 単一式関数の呼び出し
println(square(5)) // 25
println(greet("Kotlin")) // Hello, Kotlin!
println(isEven(4)) // true
println(max(10, 7)) // 10
// ローカル関数の呼び出し
val nums = listOf(1, 2, 3, 2, 4, 3, 5)
println(findDuplicates(nums)) // [2, 3]
// 階乗(ローカル関数による末尾再帰)
println(factorial(5)) // 120
println(factorial(10)) // 3628800
// 単一式関数を組み合わせる
fun cube(n: Int) = n * square(n) // square は上で定義した関数
println(cube(3)) // 27
}
概要
単一式関数は『=』を使って1行で定義できるため、シンプルな変換関数やユーティリティ関数を簡潔に書けます。ただし処理が複雑になる場合は通常の中括弧スタイルのほうが読みやすいです。
ローカル関数は外側の関数の変数にアクセスできるクロージャです。外部から呼ばれない補助ロジックをローカル関数にまとめることで、コードの見通しが良くなります。同様の目的でラムダ式も使えますが、ローカル関数は再帰が書きやすいという利点があります。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。