ラムダの定義
ラムダ式は常に中括弧で囲まれ、完全な構文形式のパラメーター宣言は中括弧で囲まれ、オプションの型注釈が付けられ、関数本体は->
記号の後に続きます 。ラムダの推定戻り値の型がではない Unit
場合、ラムダの本体の最後の(またはおそらく単一の)式が戻り値と見なされます。
これは、ラムダ式を中括弧{}で囲む必要があることを意味し ->
ます。前部はパラメーターであり、後部はこのパラメーターで実行する操作であるメソッド本体です。ラムダに戻り値がある場合、->
最後の式が戻り値と見なされます。コードは次のとおりです。
Lambda就像一个简化的函数,如下:
lam1 对应的就是method1 ,两个参数,返回一个Int值。x+y 作为 -> 后面最后一个表达式返回
var lam1: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
fun method1(x: Int, y: Int): Int {
return x + y
}
lam2 对应的就是method2,如果表达式不需要返回值,x+y 只是做了一次运算,并没有返回
var lam2: (Int, Int) -> Unit = { x: Int, y: Int -> x + y }
fun method2(x: Int, y: Int): Unit {
x + y
}
ラムダの本体の最後の(または場合によっては単一の)式が戻り値として扱われます。なぜあなたはそれを言わなければならないのですか?
var lam1: (Int, Int) -> Int = { x: Int, y: Int ->
1操作 ➺ val sum = x + y
2操作 ➺ println(sum)
3操作 ➺ sum
}
注意:Kotlin不像java用 ; 作为结束标志,所以要每行写一个操作,如果放在一行编译就会报错!
->
1、2、3の3つの演算があり、最後の3つの式が戻り値として返されます。
その後、
var lam = { x: Int, y: Int -> x + y }
前のステートメントは戻り値があるかどうかを指定していませんが、x + yは戻り値として返されますか?
var lam = { x: Int, y: Int -> x + y }
fun main() {
println(lam(2, 3))
}
打印结果:
D:\AndroidStudio\android-studio\jre\bin\java.exe -
5
Process finished with exit code 0
結果は戻り値として使用されます。指定されていない場合、戻り値は->
戻り式に従って自動的に計算されます。コードは次のとおりです。
修改1:
var lam = { x: Int, y: Int -> x > y }
打印结果
D:\AndroidStudio\android-studio\jre\bin\java.exe -
false
Process finished with exit code 0
修改2:
var lam = { x: Int, y: Int -> "Result $x $y" }
打印结果
D:\AndroidStudio\android-studio\jre\bin\java.exe -
Result 2 3
Process finished with exit code 0
================================================== =====================
ラムダのルール
私たちが通常目にするラムダの最も深い印象は、それが単純化され、最終的に1つの{}に単純化されることです。私にはわかりませんが、驚くべきことです。
関数メソッドをラムダ式に変更するにはどうすればよいですか?これは、ラムダの次の非常に重要なルールに関連しています
1 Kotlinには規則があります。関数の最後のパラメーターが関数の場合、対応するパラメーターとして渡されたラムダ式を括弧の外に配置できます。この構文は、末尾のラムダ式とも呼ばれます。
fun main() {
method3( "hello" , { x -> x + 6 } ) : 正常调用,
↓
↓
↓ 根据拖尾原则,如果lambda表达式在参数的最后一个位置
↓ 可以拿到圆括号外面
↓
method3("hello") { x -> x + 6 }
}
fun method3(msg: String, lamParams: (Int) -> Int) {
两个参数:一个String,一个lambda表达式
}
2ラムダ式にパラメーターが1つしかない場合は、このパラメーターを省略して->を無視できます。そして、この省略されたパラメータはそれに置き換えることができます
还是接着上面的代码继续修改
fun main() {
method3( "hello" , { x -> x + 6 } ) : 正常调用,
↓
↓
↓ 根据拖尾原则,如果lambda表达式在参数的最后一个位置
↓ 可以拿到圆括号外面
↓
method3("hello") { x -> x + 6 }
↓
↓ 根据单参数省略原则:
↓ 参数 x 省略,
↓ -> 省略
↓ x可用 it 代替
↓
method3("hello") { it + 6 }
}
fun method3(msg: String, lamParams: (Int) -> Int) {
两个参数:一个String,一个lambda表达式
}
この単純化の後、それは非常に強力に見えます:method3( "hello"){it + 6}
3ラムダ式のパラメーターが使用されていない場合は、その名前をアンダースコアに置き換えることができます。
fun main() {
method("") { _, str -> str }
分析:
1 lambda表达式位置在method方法中参数最后一个可以拿到括号外面
2 lambda表达式有两个参数,所以不能省略
3 Int参数 在箭头后面的操作中没有用到,可以用 _ 代替
}
fun method(msg: String, lam: (Int, String) -> String) {
}
このようにして、関数をLambda式に還元できます。
fun method5(str: String, x: Int, bool: Boolean) {
str + x + bool
}
↓
↓ 精简
↓
{ str: String, x: Int, bool: Boolean -> str + x + bool }
然后将这个Lambda表达式赋值给lam5
var lam5 = { str: String, x: Int, bool: Boolean -> str + x + bool }
main(){
method6是用method5 的函数形式作为参数
我们分别传递 method5 和 lambda5 到method6中,完全没有问题,说明精简是对的
method6(lam5)
method6(::method5)
}
fun method6(m: (String, Int, Boolean) -> Unit) {
参数是(String, Int, Boolean) -> Unit这么一个表达式
}
================================================== =====================
ラムダ表示ステートメントの戻り値:
Lambdaは、returnキーワードを直接使用することを禁止しています。限定された戻り構文を使用できます。return@ function nameLambdaから値を明示的に返します。それ以外の場合は、最後の式の値を暗黙的に返します。
lambda默认将 -> 最后一个表达式作为返回值返回
method("") { _, str -> str }
也可以显示的 return 返回值
method("") { _, str -> return@method str }
================================================== =====================
匿名関数:
指定されたラムダ式の戻り値の型を表示したい場合は、無名関数の形式を使用できます
fun(x: Int, y: Int): Int = x + y
funキーワードには通常の関数のような関数名がないため、無名関数と呼ばれます。
また、戻り値を計算できる場合は、戻り値を省略できます。つまり、fun(x:Int、y:Int)= x + yも可能です。
注意:
1無名関数のパラメーターは括弧で囲む必要があり、ラムダ式のように単純化することはできません。
2ラムダ式と無名関数のもう1つの違いは、非ローカルリターンの動作です。これはどういう意味ですか?
公式文書には次のように書かれています。ラベルのないreturnステートメントは、funキーワードで宣言された関数で常に返されます。これは、ラムダ式での戻り値がそれを含む関数から返され、無名関数での戻り値が無名関数自体から返されることを意味します。
インラインインライン関数を含む非ローカルリターン
インライン関数がLambda式に処理される場合、returnは、インライン関数自体ではなく、インライン関数を呼び出す外部関数を返すと言われています。(注:前述のように、Lambdaはreturnキーワードの直接使用を禁止しています。return@ functionnameの形式で使用する必要があります。ただし、インライン関数がLambdaを使用する場合はreturnキーワードを直接使用できます)。コードを見てください:
fun song(f: (String) -> Unit) {
}
inline fun speak(f: (String) -> Unit) {
}
fun behavior() {
song {
println("song $it")
return //此处报错: 'return' is not allowed here
}
speak {
println("speak $it")
return //此处没问题
}
}
fun main() {
behavior()
}
song() 方法没有内联不允许在 Lambda 中直接 return 所以报错。
そして、私たちの関数呼び出しシーケンスは
main() -> behavior() -> speak
このようにして、speakのラムダ式をパラメーターで返します。どの関数が終了しますか?
終わりは行動関数です。話すのはインライン関数だからです。コンパイルすると次のようになります。
调用处大体示意: 编译时大体示意:
fun main() { fun main() {
behavior { behavior {
speak {
println("speak $it") println("speak $it")
return return
}
} }
} }
したがって、戻り値は動作関数です。
(注:インライン関数が戻ることができるかどうかには他にも制限があるため、ここでは説明しません。)
上記のよう に、ラムダ式での戻り値はそれを含む関数から戻り、無名関数での戻り値は無名関数自体から戻ります。ラムダインライン関数の場合について話します。