【问题标题】:SAM Conversion with Generics使用泛型进行 SAM 转换
【发布时间】:2019-07-16 21:22:17
【问题描述】:

我的接口定义如下:

interface OnItemClickDelegate<T: Entity> {
    fun onItemClick(entity: T?)
}

现在我在不同的类中匿名定义了我的接口:

var itemClickDelegate = object : OnItemClickDelegate<Derived> {
        override fun onItemClick(entity: Derived?) {
            doSomethingWith(entity)
        }
    }

这编译得很好,但是当我把它切换到:

var itemClickDelegate = OnItemClickDelegate<Derived> { entity -> doSomethingWith(entity) }

我收到一个编译器错误提示:

Interface OnItemClickDelegate does not have constructors

如何用简短的符号写我的声明?

【问题讨论】:

标签: generics kotlin interface


【解决方案1】:

遗憾的是,Kotlin 不支持这种开箱即用的 kotlin 接口语法,只有 java 一种(无论您是否使用泛型)。

你可以这样做:


interface OnItemClickDelegate<T : Entity> {
    fun onItemClick(entity: T?)

    companion object {
        inline operator fun <T : Entity> invoke(crossinline op: (entity: T?) -> Unit) =
            object : OnItemClickDelegate<T> {
                override fun onItemClick(entity: T?) = op(entity)
            }
    }
}

这样你就可以像这样实例化一个监听器:

  val delegate = OnItemClickDelegate<Entity> {
                    //todo -> insert your callback code here
            }

【讨论】:

    【解决方案2】:

    从 Kotlin 1.4 开始,只需在接口声明前添加 fun 即可,如下所示:

    fun interface OnItemClickDelegate<T : Entity> {
        fun onItemClick(entity: T?)
    }
    

    https://kotlinlang.org/docs/whatsnew14.html#sam-conversions-for-kotlin-interfaces

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多