kotlin - 如何处理泛型类中的可为空类型
问题描述
我想在 kotlin 中写一个 Promise 类。此类使用泛型类型。该类型也可以是可为空的类型。当我调用消费者时,如果通用类型可以为空,则该值可以为空。如果不是,则必须将值设置为对象。kotlin 编译器向我显示以下消息: 智能转换为 'T' 是不可能的,因为 'value' 是一个可变属性,此时可能已更改
我理解为什么会出现此消息,但我确信此时该值必须是正确的。我怎样才能编译这个类?我试图用!!强制访问该值 但随后我的null测试将因 NPE 而失败。
java.lang.NullPointerException
at test.Promise.resolve(App.kt:20)
at test.AppTest.testPromiseNull(AppTest.kt:31)
class Promise<R> {
private var resolved = false
private var value: R? = null
var then: Consumer<R>? = null
fun resolve(r: R) = synchronized(this) {
if (resolved) error("Promise already resolved!")
value = r
resolved = true
then?.accept(value) // Smart cast to 'T' is impossible, because 'value' is a mutable property that could have been changed by this time*
}
fun then(consumer: Consumer<R>) = synchronized(this) {
if (then != null) error("Just one consumer is allowed!")
then = consumer
val value = value
if (resolved) {
consumer.accept(value) // Smart cast to 'T' is impossible, because 'value' is a mutable property that could have been changed by this time*
}
}
}
@Test fun testPromise() {
val promise = Promise<String>()
var resolved = false
promise.then {
assertEquals(it, "hello" )
resolved = true
}
promise.resolve("hello")
assert(resolved)
}
@Test fun testPromiseNull() {
val promise = Promise<String?>()
var resolved = false
promise.then {
assertNull(it)
resolved = true
}
promise.resolve(null)
assert(resolved)
}
更新 我创建了一个小帮助功能
private fun <T> uncheckedCast(t: T?): T {
@Suppress("UNCHECKED_CAST")
return t as T
}
解决方案
对于您的resolve
函数,您已经拥有可以使用的不可变参数值。
fun resolve(r: R) = synchronized(this) {
if (resolved) error("Promise already resolved!")
value = r
resolved = true
then?.accept(r)
}
在另一种情况下,由于您比编译器了解更多,您可以进行显式转换,并抑制警告。
fun then(consumer: Consumer<R>) = synchronized(this) {
if (then != null) error("Just one consumer is allowed!")
then = consumer
if (resolved) {
@Suppress("UNCHECKED_CAST")
consumer.accept(value as R)
}
}
推荐阅读
- javascript - Node.js:req.body 未定义
- typescript - typeorm - 类型“{Entity}”不可分配给类型“QueryDeepPartialEntity<{Entity}>”
- angular - 'Element | 类型的参数 null' 不可分配给“元素”类型的参数。类型“null”不可分配给类型“元素”。角
- javascript - 如何检查网页元素是否包含伪元素。爪哇
- pine-script - 松树脚本问题
- google-chrome - 谷歌选择器根本不加载
- haskell - 由于 Haskell 上的类型不兼容,Data.Text 操作发出错误
- generics - 如何返回既不是通用也不是具体的类型
- javascript - 为什么我的 webpack 入口点之一没有执行 javascript?
- javascript - 处理嵌套的异步函数以返回一个最终结果