【问题标题】:Java / Kotlin genericsJava / Kotlin 泛型
【发布时间】:2017-11-16 15:18:15
【问题描述】:

我有一个模板/泛型问题。

这是我目前的代码

data class RealmWatcher<T>(
        val results: RealmResults<T>,
        val handler: (RealmResults<T>) -> Unit)

并在 Android 片段中使用它来监听特定结果并根据更改执行操作。所以我们以这个为例

private val realmListener = arrayOf(
            RealmWatcher<Notification>(Realm.getDefaultInstance().where(Notification::class.java).equalTo("isNew", true).findAll(),
                                       { n: RealmResults<Notification> ->
                                           // DO STUFF
                                       })

我在片段的开始/停止时这样做

override fun onResume() {
    super.onResume()
    // start listening and execute
    realmListener.forEach { it.handler(it.results) }
    realmListener.forEach { it.results.addChangeListener(it.handler) }
}

override fun onPause() {
    // stop listening
    realmListener.forEach { it.results.removeChangeListener(it.handler) }
    super.onPause()
}

它仅在我使用一种类型时才有效(例如上面的Notification)。如果我想以

的形式使用不同的类型,我应该如何定义
private val realmListener = arrayOf(
            RealmWatcher<Notification>(Realm.getDefaultInstance().where(Notification::class.java).equalTo("isNew", true).findAll(),
                                       { n: RealmResults<Notification> ->
                                       // TODO STUFF
                                       }),
            RealmWatcher<Project>(Realm.getDefaultInstance().where(Project::class.java).equalTo("isOdd", true).findAll(),
                                       { n: RealmResults<Project> ->
                                         // TODO STUFF
                                       })
                                       )

当混合类型(NotificationProject)时,我会收到 Type mismatch 错误。

并且在定义时

private val realmListener:Array<RealmWatcher<out Any>>

我也会收到Type mismatch 错误

如何定义 Array 以拥有多个不同类型 T 的 RealmWatcher?

【问题讨论】:

  • 嗯,你能发布实际错误以及它们发生的位置吗?
  • 在你的领域观察者类上放置差异,即data class RealmWatcher&lt;out T&gt;
  • @SimY4 这不起作用,因为T 也用于代码中的in 位置。请参阅我的答案以获得更好地封装逻辑的工作解决方案。

标签: java android templates generics kotlin


【解决方案1】:

完全按照您的意愿去做会很棘手,因为我不知道有什么方法可以告诉编译器您正在做的事情实际上是安全的。像其中一个 cmets 所建议的那样,添加方差不会起作用,因为 T 用于 inout 位置。

但是,您可以采取不同的方法。像这样扩展您的RealmWatcher

data class RealmWatcher<T>(
    val results: RealmResults<T>,
    val handler: (RealmResults<T>) -> Unit
) {
    fun attach() {
        handler(results)
        results.addChangeListener(handler)
    }
    fun detach() {
        results.removeChangeListener(handler)
    }
}

然后在你的生命周期回调中使用这两个额外的函数:

fun onResume() {
    super.onResume()
    // start listening and execute
    realmListener.forEach { it.attach() }
}

fun onPause() {
    // stop listening
    realmListener.forEach { it.detach() }
    super.onPause()
}

这将做你需要它做的事情,而不会因为混合的泛型参数而产生问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多