功能參考

我們可以通過在函式的名稱前加上::來引用函式而不實際呼叫它。然後可以將其傳遞給接受一些其他函式作為引數的函式。

fun addTwo(x: Int) = x + 2
listOf(1, 2, 3, 4).map(::addTwo) # => [3, 4, 5, 6]

沒有接收器的函式將轉換為 (ParamTypeA, ParamTypeB, ...) -> ReturnType,其中 ParamTypeAParamTypeB …是函式引數的型別,`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
}