Kotlin - ラムダ式
公開日:2019-11-06 更新日:2019-11-06
[Kotlin]
1. 概要
ラムダ式とは、無名関数をさらにシンプルにしたようなものです。
関数の引数をラムダ式にすることで、関数の処理の一部を外部に任せることができます。
関数の引数をラムダ式にすることで、関数の処理の一部を外部に任せることができます。
{ 引数1 -> 式 }
{ 引数1:型, ... , 引数n:型 ->
処理
処理
戻り値
}
2. 基本
コレクションの forEach() はラムダ式や無名関数を引数として受け取ります。
実行すると、リストの各要素をラムダ式の引数として、ラムダ式を実行します。
以下の例では、ラムダ式が5回実行されます。
メソッドの引数は ( ) 内に指定しますが、ラムダ式の場合は ( ) を省略できます。
ラムダ式の引数が1つの場合は引数を省略できます。その場合の引数は it になります。
上記を省略しないで書くと以下のようになります。
戻り値を返す時は、変数かリテラル値を書くだけです。return は不要です。
return をすると、ラムダ式からではなく、親の関数から抜けるので要注意です。
実行すると、リストの各要素をラムダ式の引数として、ラムダ式を実行します。
以下の例では、ラムダ式が5回実行されます。
メソッドの引数は ( ) 内に指定しますが、ラムダ式の場合は ( ) を省略できます。
ラムダ式の引数が1つの場合は引数を省略できます。その場合の引数は it になります。
val lst = listOf(1, 2, 3, 4, 5)
lst.forEach {
print(it)
} //12345
上記を省略しないで書くと以下のようになります。
val lst = listOf(1, 2, 3, 4, 5)
lst.forEach({n:Int ->
print(n)
}) //12345
戻り値を返す時は、変数かリテラル値を書くだけです。return は不要です。
return をすると、ラムダ式からではなく、親の関数から抜けるので要注意です。
val lst = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val lst2 = lst.filter {
val result = (it % 2 == 0)
result // 戻り値。return は不要
}
println(lst2) // [2, 4, 6, 8, 10]
3. 引数が複数のラムダ式
他の言語では引数を ( ) で囲む場合がありますが、
kotlin は ( ) で囲むとエラーになるので注意してください。
kotlin は ( ) で囲むとエラーになるので注意してください。
val add = { v1:Int, v2:Int -> v1 + v2 }
println( add(1, 2) ) // 3
4. ラムダ式を関数の引数にする
ラムダ式を関数の引数にする場合は、引数に関数の型を定義します。
この時の引数は ( ) で囲む必要があるので要注意です。
また、引数の最後にラムダ式を指定する場合は、ラムダ式を ( ) の外に定義できます。
この時の引数は ( ) で囲む必要があるので要注意です。
また、引数の最後にラムダ式を指定する場合は、ラムダ式を ( ) の外に定義できます。
fun calc(v1:Int, v2:Int, f:(Int, Int) -> Int):Int {
return f(v1, v2)
}
//左辺と右辺のどちらかで型がわかる場合は、型の省略が可能です
val add1:(Int, Int) -> Int = { v1:Int, v2:Int -> v1 + v2 }
val add2:(Int, Int) -> Int = { v1, v2 -> v1 + v2 }
val add3 = { v1:Int, v2:Int -> v1 + v2 }
//val add4 = { v1, v2 -> v1 + v2 } //型推論できないためエラー
println(calc( 1, 2, add1)) // 3
println(calc( 1, 2, add2)) // 3
println(calc( 1, 2, add3)) // 3
println(calc( 1, 2, { v1, v2 -> v1 + v2 } )) // 3
//引数の最後にラムダ式を指定する場合は、( ) の外に定義できます
println(calc(1, 2) {
v1, v2 -> v1 + v2 }
) // 3
5. ラムダ式で return
ラムダ式の途中で return したい場合は、「return@親の関数名」か「return@ラベル」とします。
「return@親の関数名」で抜ける
「return@ラベル」で抜ける
「return@親の関数名」で抜ける
val list1 = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val list2 = list1.filter{
if (it > 6) return@filter false
it % 2 == 0
}
println(list2) // [2, 4, 6]
「return@ラベル」で抜ける
val list1 = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val list2 = list1.filter test@ {
if (it > 6) return@test false
it % 2 == 0
}
println(list2) // [2, 4, 6]
6. ブロック不可
他の言語では { } でブロックにして、ローカル変数の重複を避けることができますが、
kotlin では、ラムダ式として扱われます。
以下の場合、test() 内のブロックはラムダ式として扱われるため、何も処理されません。
ラムダ式の後ろに ( ) を付けるとその場で実行できるため、それを利用してブロックのように使うことはできます。
但し、書き方によっては、文末に「;」セミコロンを付けないとコンパイルエラーになるため、要注意です。
kotlin では、ラムダ式として扱われます。
以下の場合、test() 内のブロックはラムダ式として扱われるため、何も処理されません。
fun test() {
{
println("test")
}
}
test()
ラムダ式の後ろに ( ) を付けるとその場で実行できるため、それを利用してブロックのように使うことはできます。
但し、書き方によっては、文末に「;」セミコロンを付けないとコンパイルエラーになるため、要注意です。
fun test() {
val a = 1
val b = 2
var c = 0
{
val a = 100
c = a + b
}( )
println(c); // 102。「;」をはずすとエラーになる
{
c = a + b
}( )
println(c) // 3
}
test()