【问题标题】:Kotlin put generic type object into specific hashmapKotlin 将泛型类型对象放入特定的 hashmap
【发布时间】:2019-03-03 22:48:45
【问题描述】:

我在 Kotlin 中做一个小型库,它在配置更改期间处理演示者。我创建了演示者商店类,我将在其中保留演示者。我使用泛型类,但我有问题,但也许我会给你看代码。

interface AbstractStore {
    fun clear()
    fun <V : AbstractView> put(key: String, presenter: Presenter<V>)
    fun <V : AbstractView> get(key: String): Presenter<V>? 
}

抽象存储的实现

class PresenterStore : AbstractStore {

    private val mMap = HashMap<String, Presenter<AbstractView>>()

    override fun <V : AbstractView> put(key: String, presenter: Presenter<V>) {
        mMap[key] = presenter   // problem is here. I can't do this in that way.
    }

    override fun <V : AbstractView> get(key: String): Presenter<V>? {
        return mMap[key]
    }

    /**
     * Clears internal storage that Presenters are no longer used.
     */
    override fun clear() {
        mMap.forEach { (_, presenter) -> presenter.onDestory() }
        mMap.clear()
    }
}

put 方法有问题。我得到的消息:

Error:(12, 10) Type inference failed: Cannot infer type parameter V in operator inline fun <K, V> MutableMap<K, V#1 (type parameter of kotlin.collections.set)>.set(key: K, value: V#1): Unit
None of the following substitutions
receiver: MutableMap<String, Presenter<AbstractView>>  arguments: (String,Presenter<AbstractView>)
receiver: MutableMap<String, Presenter<V#2 (type parameter of com.xxxx.mvp.presenter.PresenterStore.put)>>  arguments: (String,Presenter<V#2>)
can be applied to
receiver: HashMap<String, Presenter<AbstractView>>  arguments: (String,Presenter<V#2>)

我不明白发生了什么,但是如果我将其更改为

mMap[key] = presenter as Presenter&lt;AbstractView&gt; 然后使用警告

Unchecked cast: Presenter<V> to Presenter<AbstractView>

有没有可能在不强制转换的情况下保留方法?为什么 Kotlin 不知道 Presenter 是具有 AbstractView 子类型的泛型类?

【问题讨论】:

    标签: android generics kotlin


    【解决方案1】:

    不要让这两个方法独立泛型,而是像这样使用类类型参数:

    interface AbstractStore <V : AbstractView> {
        fun clear()
        fun put(key: String, presenter: Presenter<V>)
        fun get(key: String): Presenter<V>? 
    }
    

    然后,在实现中,定义一个具体的类型:

    class PresenterStore : AbstractStore<ConcreteView> {
    
        override fun put(key: String, presenter: Presenter<ConcreteView>) {
            mMap[key] = presenter
        }
    
        override fun get(key: String): Presenter<ConcreteView>? {
            return mMap[key]
        }
    
        private val mMap = HashMap<String, Presenter<ConcreteView>>()
    }
    

    现在它可以工作并且完全是类型安全的。

    【讨论】:

    • 谢谢。最简单的最好。
    猜你喜欢
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多