android - Kotlin、泛型和可能没有参数的函数

标签 android kotlin

我正在尝试围绕一个非常常见的模式来通用化样板文件,而 Kotlin 让我非常接近。

我构建了一个充当监听器管理器的类,如下所示:

class GenericListenerSupport <EventArgumentType, ListenerFunction: (EventArgumentType) -> Unit> {
    private val listeners = mutableListOf<ListenerFunction>()

    fun addListener(listener: ListenerFunction) {
        listeners.add(listener)
    }

    fun removeListener(listener: ListenerFunction) {
        listeners.remove(listener)
    }

    fun fireListeners(argument: EventArgumentType) {
        listeners.forEach { it.invoke(argument) }
    }
}

它可以按如下方式使用:

class ExampleWithArgument {
    private val listenerSupport = GenericListenerSupport<String, (String)->Unit>()

    fun exampleAdd() {
        listenerSupport.addListener({ value -> System.out.println("My string: "+value)})
    }

    fun exampleFire() {
        listenerSupport.fireListeners("Hello")
    }
}

到目前为止,一切都很好。但如果听者没有论据怎么办?或者进一步延伸,多个参数。

我可以用这个勉强度日:

class ExampleWithNoArgument {
    private val listenerSupport = GenericListenerSupport<Nothing?, (Nothing?)->Unit>()

    fun exampleAdd() {
        listenerSupport.addListener({ System.out.println("I've got no argument")})
    }

    fun exampleFiring() {
        listenerSupport.fireListeners(null)
    }
}

但是有味道,而且显然多个参数没有用。

有没有更好的方法来实现这一点?例如支持这个概念的东西:

private val listenerSupport = GenericListenerSupport<???, (String, Double)->Unit>()

最佳答案

由于您的 GenericListenerSupport 声明了一个类型参数 EventArgumentType 并期望在 fun fireListeners(argument: EventArgumentType) 中有一个它的实例,我怀疑您可以以干净的方式支持多个参数。相反,我建议使用数据类(这不是太多额外的代码),作为包装多个值的干净且类型安全的方法:

data class MyEvent(val id: String, val value: Double)

private val listenerSupport = GenericListenerSupport<MyEvent, (MyEvent) -> Unit>()

至于不传递值,还可以使用Unit,只有一个值的类型Unit:

listenerSupport.fireListeners(Unit)

类型系统和解析不允许您在需要单个参数的情况下不传递任何参数,但是,如 @Ruckus T-Boom建议,您可以在需要 Unit 的地方进行扩展来触发没有值的监听器:

fun GenericListenerSupport<Unit>.fireListeners() = fireListeners(Unit)

有点离题,但我认为如果您不需要自定义函数类型并且 (EventArgumentType) -> Unit 就足够了,您可以简化类型:

class GenericListenerSupport<EventArgumentType> {
    /* Just use `(EventArgumentType) -> Unit` inside.  */
}

关于android - Kotlin、泛型和可能没有参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45987685/

相关文章:

java - RecyclerView 项目内容混淆

android - Servlet 在带有 Android 客户端的 AppEngine 中不可用

java - 启动器 Activity 未启动并崩溃

algorithm - 使用 A* 搜索算法解决Theseus 和 Minotaur 谜题

scala - Kotlin相当于Scala Traversable.collect

android - 为什么 renderscript 示例代码在模拟器上不起作用?(Android)

android - 如何在缩放位图上获取像素颜色值?

generics - 有限制的通配符类型的kotlin等效于Java注释字段是什么?

android - 在android中创建另一个字符串xml值文件

android - 华为广告工具包横幅广告返回错误代码1