【发布时间】:2019-10-27 15:46:33
【问题描述】:
弄乱以下示例代码让我意识到我对 Kotlin 何时推断平台类型感到困惑:
inline fun <reified U, V> LiveData<U>.map(crossinline f: (U) -> V): LiveData<V> {
val result = MediatorLiveData<V>()
result.addSource(this) { u -> // u: U!
if (u is U) {
result.value = f(u)
}
}
return result
}
val x = MutableLiveData<Int>()
val y = x.map { it + 1 }
x.value = 1 // ok
x.value = null // will eventually crash from doing null + 1
我希望当u 是null 时,reified+crossinline 的这种使用会阻止map 函数调用f,因为它会检查是否null is Int。不过有趣的是,null 偷偷溜过支票。
我想我一定是误解了 reified+crossinline 的工作原理,但似乎真正有问题的是类型推断:U 似乎被推断为Int!,而不是Int。例如,手动指定map 的类型参数可以让事情发挥作用:
val y = x.map<Int, Int> { it + 1 }
所以。为什么 Kotlin 会推断出上面的平台类型? (毕竟,x 推断类型为MutableLiveData<Int>,而不是MutableLiveData<Int!>。)除了自己进行推断之外,有没有办法不推断平台类型?
【问题讨论】:
标签: generics kotlin android-livedata kotlin-reified-type-parameters