简体   繁体   中英

Type inference failed. MutableMap<Class<out AbsViewModel>, Provider<AbsViewModel>>

kotlin 1.5 changes a type inference warning (present in 1.4) into an error. Is there anyway to ignore the error in 1.5? Currently, I need to downgrade to 1.4 to compile the code.

"Type inference failed. The value of the type parameter K should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly."

--> providerMap[modelClass]

class ViewModelFactory @Inject constructor(private val providerMap: MutableMap<Class<out AbsViewModel>, Provider<AbsViewModel>>) : ViewModelProvider.Factory {
    @Suppress("TYPE_INFERENCE_ONLY_INPUT_TYPES_WARNING", "UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        (providerMap[modelClass]?.get() as? T)?.let { return it }
        throw Exception("Could not find view model for ${modelClass.canonicalName}")
    }

}
class ViewModelFactory @Inject constructor(
    private val providerMap: MutableMap<Class<out AbsViewModel>,
            Provider<AbsViewModel>>) : ViewModelProvider.Factory {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        (providerMap[modelClass as Class<out AbsViewModel>]?.get() as? T)?.let { return it }
        throw Exception("Could not find view model for ${modelClass.canonicalName}")
    }
}

Either make the input type of your Map key Class a wildcard:

class ViewModelFactory @Inject constructor(
    private val providerMap: MutableMap<Class<*>,
            Provider<AbsViewModel>>
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        @Suppress("UNCHECKED_CAST")
        (providerMap[modelClass]?.get() as? T)?.let { return it }
        throw Exception("Could not find view model for ${modelClass.canonicalName}")
    }
}

Or if you prefer to enforce the type in the constructor, cast the key:

class ViewModelFactory @Inject constructor(
    private val providerMap: MutableMap<Class<out AbsViewModel>,
            Provider<AbsViewModel>>
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        @Suppress("UNCHECKED_CAST")
        (providerMap[modelClass as Class<AbsViewModel>]?.get() as? T)?.let { return it }
        throw Exception("Could not find view model for ${modelClass.canonicalName}")
    }
}

And either way you can simplify your return/throw using ?: instead of ?.let :

return providerMap[modelClass]?.get() as? T 
    ?: error("Could not find view model for ${modelClass.canonicalName}")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM