为什么 lateinit 不能与 elvis 运算符一起工作,以及它与 optionals 有何具体不同

why doesn't lateinit work with the elvis operator, and how specifically is it different from optionals

假设我有以下 class:

class ExampleClass: OtherClass {
  lateinit var thing: Thing
  var thingOptional: Thing? = null
  fun exampleFun() {
    val innerThing = thing ?: Thing()
    val innerThing2 = thingOptional ?: Thing()
  }
}

产生以下警告:

Elvis operator (?:) always returns the left operand of non-nullable type Thing

然后是以下运行时异常:

lateinit property thing has not been initialized

所以在我的理解中,可选的可以是类型,也可以是任何时候的 null,而 lateinit 变量可以为 null,直到它被赋予一个值,然后再也不能为 null,并且必须被赋予一个值。但是很明显 lateinit 的语义略有不同。

所以:lateinit 的起始值是多少,为什么它不是假的?是否可以以这种方式使用 lateinit 作为可选替代品?如果没有,我如何创造这种价值? (允许 null 作为起始状态,但随后不可为 null)

您仍然需要在执行任何读取之前手动为 lateinit 字段分配一个值,该标志所做的只是减轻了在构造函数中对其进行初始化的需要。 lateinit doc

如您所见,lateinit 字段没有初始值 - 它在读取时抛出异常,但您可以手动检查它是否已使用 this::thing.isInitialized.

初始化

所以基本上 Kotlin 中发生的事情,lateinit 只是意味着您不需要在声明该变量时对其进行初始化,但是您有责任在读取或访问它之前对其进行初始化,否则它会在 运行 时间抛出异常。

当您使用依赖注入进行初始化时,它基本上很有用。

现在谈谈你的错误,

Elvis operator (?:) always returns the left operand of non-nullable type Thing

您遇到上述错误是因为您在初始化之前访问 lateinit var thing 并且在您的另一个错误中明确说明

lateinit property thing has not been initialized

现在,回答这个问题:

如果没有,我该如何创造这样的价值? (允许 null 作为起始状态,但不能为 nullable)

你可以这样做:

  class ExampleClass: OtherClass {
  var thingOptional: Thing? = null
  fun exampleFun() {
    thingOptional = Thing()// thingsOption was null initially but now it is initialized
  }
}

希望对您有所帮助,如果您还有其他疑问,请告诉我。