代码之家  ›  专栏  ›  技术社区  ›  Travis Griggs

为什么我必须在闭包中包装我的Kotlin方法引用?

  •  0
  • Travis Griggs  · 技术社区  · 7 年前

    在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是否不在同一基础上?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Salem    7 年前

    在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 表示被调用函数的实例 把手通风口 ,因为这与lambda签名匹配 (ByteArray) -> Unit 它按预期工作。

    请注意,这与C语言或C++不同,在这里,由于语言限制,方法和属性/字段不能共享相同的名称。用这些语言 . 对于方法组/函数指针是可以的,因为不可能 foo.bar 会模棱两可。

        2
  •  0
  •   Pawel    7 年前

    在第行中计算(调用)不带闭包的表达式。

    闭包使用定义的方法(闭包内)生成匿名对象,在需要时可以调用该方法。

    唯一的例外是当使用lambda的函数声明为 inline 在这种情况下,整个函数块被注入调用位置,包括lambda(以防止生成对象)。