ラムダを書くことができますid_Int
およびid_Boolean
明示的なタイプ。そして、typeパラメーターを使用して関数identity
を記述できます。 typeパラメーターを使用してラムダを記述できますか?
fun testFuncInt(f: (Int) -> Int): Int = f(1) + 2
val id_Int = { x: Int -> x }
fun testFuncBoolean(f: (Boolean) -> Boolean): Boolean = !f(false)
val id_Boolean = { x: Boolean -> x }
fun <T> identity(x: T) = x
fun main(args: Array<String>) {
println(testFuncInt(id_Int))
println(testFuncInt(::identity))
println(testFuncBoolean(id_Boolean))
println(testFuncBoolean(::identity))
}
Kotlinは、クラスレベルでその型を宣言せずにジェネリックプロパティを宣言することをサポートしていません( 参照 )が、目的の型に対応するラムダを返す関数を使用して行うことができます。
fun main(args: Array<String>) {
println(testFuncBoolean(id()))
println(testFuncInt(id()))
}
fun <T> id(): (T) -> T = { it }
fun testFuncInt(f: (Int) -> Int): Int = f(1) + 2
fun testFuncBoolean(f: (Boolean) -> Boolean): Boolean = !f(false)
いいえ、しかしあなたは一般的にそうする必要はありません。ラムダには宣言がないため(これは一種のポイントです)、本質的には関数に渡すことができる式であり、val id_Boolean = { x: Boolean -> x }
を実行するときと同じように、val
/var
に格納しますがタイプは、式の場合と同じように実際に処理されます。
ここでの呼び出しは正しい型に解決されます。これは、関数がInt
を受け取ってInt
を返す関数と、Boolean
を受け取ってBoolean
testFuncInt({ x -> x }) // x is an Int
testFuncInt({ it }) // it is the default argument
testFuncInt { x -> x } // as top one, Kotlin's syntactic sugar
ここで重要なことは、ラムダ式がまだ型安全性を提供することです。つまり、このようなことをした場合です。
fun <T> foo(x: T, lambda: (T) -> Boolean): Boolean = lambda(x)
foo(42, { x -> x }) // oops, lambda takes a T and returns a T
lambda
の型がfoo
が期待するものと一致しないため、これはコンパイラエラーをトリガーします。つまり、foo
はInt
をラムダに渡し、 Boolean
戻る。一方、これを行う場合
foo(123, { it == 42 })
foo(123) { it == 42 } // equivalent to above
戻り値の型は実際にはBoolean
であると推定されます。これは、比較演算の結果が評価されるものであり、123と42は同じ型であるため、lambda
の型は実際にはfoo
が期待します。
ジェネリックスでラムダを書くことはできません、なぜ公式ドキュメントから取られた次の段落はそれをすべて言います。
ラムダ式または無名関数は「関数リテラル」です。つまり、宣言されていないが、式としてすぐに渡される関数です。
ラムダ式または関数は宣言されておらず、無名関数です。
しかし、最終的には、関数型をジェネリックとして宣言することで同じことを行います。その仕事をするラムダ式を渡すことができます。
fun testFuncInt(f: (Int) -> Int): Int = f(1) + 2
あなたはそれを次のように呼ぶことができます:testFuncInt{ a -> a }
またはtestFuncInt{ it }
つまり、最終的に同じことを実行します(型パラメーターを持つラムダ)が、ラムダは式または無名関数であるため、そのような用語はありません。
それが役に立てば幸い。