功能參考
我們可以通過在函式的名稱前加上::
來引用函式而不實際呼叫它。然後可以將其傳遞給接受一些其他函式作為引數的函式。
fun addTwo(x: Int) = x + 2
listOf(1, 2, 3, 4).map(::addTwo) # => [3, 4, 5, 6]
沒有接收器的函式將轉換為 (ParamTypeA, ParamTypeB, ...) -> ReturnType
,其中 ParamTypeA
,ParamTypeB
…是函式引數的型別,`ReturnType1 是函式返回值的型別。
fun foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
//...
}
println(::foo::class.java.genericInterfaces[0])
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar
帶接收器的函式(無論是擴充套件函式還是成員函式)具有不同的語法。你必須在雙冒號之前新增接收器的型別名稱:
class Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
//...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0])
// kotlin.jvm.functions.Function4<Foo, Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo, Foo0, Foo1, Foo2) -> Bar
// takes 4 parameters, with receiver as first and actual parameters following, in their order
// this function can't be called like an extension function, though
val ref = Foo::foo
Foo().ref(Foo0(), Foo1(), Foo2()) // compile error
class Bar {
fun bar()
}
print(Bar::bar) // works on member functions, too.
但是,當函式的接收器是一個物件時,接收器在引數列表中被省略,因為它們只是這種型別的一個例項。
object Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
//...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0])
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar
// takes 3 parameters, receiver not needed
object Bar {
fun bar()
}
print(Bar::bar) // works on member functions, too.
從 kotlin 1.1 開始,函式引用也可以繫結到一個變數,然後稱為有界函式引用。
Version >= 1.1.0
fun makeList(last: String?): List<String> {
val list = mutableListOf("a", "b", "c")
last?.let(list::add)
return list
}
請注意,此示例僅用於顯示有界函式引用的工作原理。所有其他感官都是不好的做法。
但是有一個特例。無法引用宣告為成員的擴充套件函式。
class Foo
class Bar {
fun Foo.foo() {}
val ref = Foo::foo // compile error
}