Kotlin将泛型类型对象放入特定的hashmap中

时间:2018-02-23 19:55:33

标签: android generics kotlin

我在Kotlin做小型图书馆,在配置更改期间处理演示者。我创建了演示者商店类,我将保留演示者。我使用泛型类,但我有问题,但也许我会告诉你代码。

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

和Abstract Store的实现

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<AbstractView>然后使用警告

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

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

1 个答案:

答案 0 :(得分: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>>()
}

现在它起作用并且完全是类型安全的。