功能参考
我们可以通过在函数的名称前加上::
来引用函数而不实际调用它。然后可以将其传递给接受一些其他函数作为参数的函数。
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
}