在Kotlin中,我正在尝试创建一个调度表:
class Foo {
fun handleEvent(bytes:ByteArray) {
// do something fun with the bytes
}
}
class Bar {
fun handleEvent(bytes:ByteArray) {
// do something fun with the bytes
}
}
foo = Foo()
bar = Bar()
val eventHandlers:HashMap<RemoteEvent, (bytes:ByteArray)->Unit> = hashMapOf(
0x01 to foo.handleEvent,
0x02 to bar.handleEvent)
科特林似乎不喜欢这种说法,它有多种抱怨方式,但其中一个似乎是function invocation expected
。
我可以通过将它们包装在闭包中来解决此问题:
val eventHandlers:HashMap<RemoteEvent, (bytes:ByteArray)->Unit> = hashMapOf(
0x01 to { bytes -> foo.handleEvent(bytes) },
0x02 to { bytes -> bar.handleEvent(bytes) })
还有别的办法吗?为什么我必须在相同的闭包中使用正确的方法签名?在Kotlin中,闭包和方法是否处于同一立场?
答案 0 :(得分:4)
在Kotlin中,函数引用是使用::
运算符(不是.
)创建的。
使用以下方法可以轻松实现您的预期用例:
val eventHandlers: HashMap<RemoteEvent, (bytes: ByteArray) -> Unit> = hashMapOf(
0x01 to foo::handleEvent,
0x02 to bar::handleEvent)
// ^
Function references,Kotlin文档
foo.handleEvent
被解释为访问名为handleEvent
(不存在)的属性。
foo::handleEvent
是一个KFunction
实例,表示名为handleEvent
的函数,由于它与lambda签名(ByteArray) -> Unit
匹配,因此可以正常工作。
请注意,这与例如C#或C ++,由于语言限制,方法和属性/字段不能共享相同的名称。在这些语言中,.
适用于方法组/函数指针,因为foo.bar
不可能是模棱两可的。
答案 1 :(得分:0)
在没有闭包的情况下,对表达式进行评估(调用)。
闭包生成具有定义方法(在闭包内)的匿名对象,可以在需要时调用该对象。
只有在将使用lambda的函数声明为inline
的情况下例外,在这种情况下,整个功能块(包括lambda)都被注入到调用位置(以防止生成对象)。