代码之家  ›  专栏  ›  技术社区  ›  Sira Lam

如何声明使用lambda的接口?[重复]

  •  1
  • Sira Lam  · 技术社区  · 7 年前

    我声明了这样一个简单的接口:

       interface OnSomethingReadyListener {
            fun onSomethingReady()
        }
    

    当然还有二传手:

    private val onSomethingReadyListeners = ArrayList<OnSomethingReadyListener>()
    
    fun addOnSomethingReadyListener(callback: OnSomethingReadyListener) {
        onSomethingReadyListeners.add(callback)
    }
    

    但后来我发现我不能使用lambda:

    something.addOnShopDataReadyListener { progressbar.visibility = View.GONE }
    

    IDE给了我一个错误:

    Type mismatch.
    Required: SomeClass.OnSomethingReadyListener
    Found:    () -> Unit
    

    假设我想坚持使用lambda而不是匿名类( object : OnSomethingReadyListener {...} )1.我该如何申报 OnSomethingReadyListener ?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Bryan Herbst acclux    7 年前

    SAM(单一抽象方法)转换仅支持Java接口,不支持Kotlin接口。

    The documentation 陈述了以下理由:

    还请注意,此功能仅适用于Java互操作;由于Kotlin具有适当的函数类型,因此不需要将函数自动转换为Kotlin接口的实现,因此不受支持。

    KT-7770 requests this functionality ,如果您想跟踪是否正在考虑。

    实现您想要的目标的推荐方法是替换 OnSomethingReadyListener 使用类型为的参数 () -> Unit 就像这样:

    private val onSomethingReadyListeners = ArrayList<() -> Unit>()
    
    fun addOnSomethingReadyListener(callback: () -> Unit) {
        onSomethingReadyListeners.add(callback)
    }
    

    然后,您可以使用以下命令调用这些侦听器

    onSomethingReadyListeners.forEach { it.invoke() }
    
        2
  •  0
  •   Luca Nicoletti    7 年前

    您必须将函数声明为:

    fun addOnSomethingReadyListener(block: (OnSomethingReadyListener) -> Unit)
    

    然后你可以这样称呼它:

    addOnSomethingReadyListener {
      // TODO
    }