为什么我必须将我的 Kotlin 方法引用包装在闭包中?
Why do I have to wrap my Kotlin method references in closures?
在 kotlin 中,我正在尝试创建调度 table:
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)
Kotlin 似乎不喜欢这样,它以多种方式抱怨,但相关的似乎是 function invocation expected
。
我可以通过将它们包装在闭包中来解决这个问题:
val eventHandlers:HashMap<RemoteEvent, (bytes:ByteArray)->Unit> = hashMapOf(
0x01 to { bytes -> foo.handleEvent(bytes) },
0x02 to { bytes -> bar.handleEvent(bytes) })
没有别的办法了吗?为什么我必须在相同的闭包中使用正确的方法签名?闭包和方法在 Kotlin 中不是同一个立足点吗?
在没有闭包的情况下,表达式在行中求值(调用)。
闭包生成一个匿名对象,该对象具有已定义的方法(在闭包内),可以在需要时调用。
唯一的例外是当使用 lambda 的函数被声明为 inline
时,在这种情况下整个函数块被注入到调用位置,包括 lambda(以防止生成对象)。
在 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++,由于语言限制,方法和 properties/fields 不能共享相同的名称。在这些语言中,.
适用于方法 groups/function 指针,因为 foo.bar
不可能有歧义。
在 kotlin 中,我正在尝试创建调度 table:
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)
Kotlin 似乎不喜欢这样,它以多种方式抱怨,但相关的似乎是 function invocation expected
。
我可以通过将它们包装在闭包中来解决这个问题:
val eventHandlers:HashMap<RemoteEvent, (bytes:ByteArray)->Unit> = hashMapOf(
0x01 to { bytes -> foo.handleEvent(bytes) },
0x02 to { bytes -> bar.handleEvent(bytes) })
没有别的办法了吗?为什么我必须在相同的闭包中使用正确的方法签名?闭包和方法在 Kotlin 中不是同一个立足点吗?
在没有闭包的情况下,表达式在行中求值(调用)。
闭包生成一个匿名对象,该对象具有已定义的方法(在闭包内),可以在需要时调用。
唯一的例外是当使用 lambda 的函数被声明为 inline
时,在这种情况下整个函数块被注入到调用位置,包括 lambda(以防止生成对象)。
在 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++,由于语言限制,方法和 properties/fields 不能共享相同的名称。在这些语言中,.
适用于方法 groups/function 指针,因为 foo.bar
不可能有歧义。