gpt4 book ai didi

kotlin - 是否有一种优雅的 kotlin 方式可以让编译器相信我刚刚为其分配了真实值的可空字段不能再为空?

转载 作者:行者123 更新时间:2023-12-02 13:08:44 27 4
gpt4 key购买 nike

我已经阅读了!一般应避免。
有没有办法以更优雅的方式编写以下代码,而不必添加诸如过时的空检查和重复或死代码块之类的东西?

class A(var field: Thing?) {
fun getField(): Thing {
if (field == null) {
field = Thing()
}
return field!!
}
}

我也不明白为什么编译器需要 !!-'pray-this-isn't-null-operator' 在这种情况下得到满足。

编辑:考虑到如果字段为空,潜在的解决方案使用延迟初始化对我来说很重要!

最佳答案

问题

正如 Enzokie 在评论中已经提到的那样,另一个线程可能在 null 检查后更改了字段。编译器无法知道这一点,所以你必须告诉它。

class A(var field: Thing?) {

fun getField(): Thing {
if (field == null) {
field = Thing()
}

// another thread could have assigned null to field

return field!! // tell the compiler: I am sure that did not happen
}
}

解决方案(急切)

在您的特殊情况下,最好使用参数 f (您也可以将其命名为“字段”,但为了清楚起见,我避免使用它)在构造函数中(没有 val/ var ),然后将其分配给属性 field分配给 fThing 的新实例.

这可以用 Elvis 运算符 :? 非常简洁地表达。如果不为空,则取左侧,否则取表达式的右侧。因此,最后字段的类型为 Thing .
class A(f: Thing?) {
val field = f ?: Thing() // inferred type Thing
}

解决方案(懒人)

由于 gidds 提到了它, 如果你需要懒惰地初始化字段,你可以使用 delegated properties :
class A(f: Thing?) {
val field by lazy {
f ?: Thing() // inferred type Thing
}
}

调用站点不变:
val a = A(null) // field won't be initialized after this line...
a.field // ... but after this

关于kotlin - 是否有一种优雅的 kotlin 方式可以让编译器相信我刚刚为其分配了真实值的可空字段不能再为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54375200/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com