为什么不与elvis运营商合作,以及它与选项有何不同

时间:2018-06-02 18:03:21

标签: kotlin optional kotlin-lateinit

说我有以下课程:

self.energyProgressBar = SKProgressBar.init(baseColor: .white, coverColor: .blue, size: CGSize(width:200,height:50))
addChild(self.energyProgressBar)
// other code to see progress changing..
let wait = SKAction.wait(forDuration: 2.0)
let action1 = SKAction.run {
    self.energyProgressBar.setProgress(0.7)
}
let action2 = SKAction.run {
    self.energyProgressBar.setProgress(0.0)
}
let action3 = SKAction.run {
    self.energyProgressBar.setProgress(1.0)
}
let action4 = SKAction.run {
    self.energyProgressBar.setProgress(0.5)
}
let action5 = SKAction.run {
    self.energyProgressBar.setProgress(0.1)
}
let sequence = SKAction.sequence([wait,action1,wait,action2,wait,action3,wait,action4,wait,action5])
self.run(sequence)

产生以下警告:

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

所以在我的理解中,一个可选的可以是一个类型,或者在任何一点都是null,而lateinit property thing has not been initialized 变量可以为null,直到给它一个值然后再也不能为null,并且必须给出一个值。但很明显lateinit的语义略有不同。

那么:lateinit的起始值是什么,为什么它不是假的呢?是否可以以这种方式使用lateinit作为可选替代?如果没有,我怎样才能创造这种价值? (允许null作为起始状态,但随后不可为空)

2 个答案:

答案 0 :(得分:3)

在执行任何读取之前,您仍然必须手动为lateinit字段分配值,所有标记都可以减少在构造函数中初始化它的需要。 lateinit doc

由于您已注意到lateinit字段没有初始值 - 它会在读取时抛出异常,但您可以手动检查它是否已使用this::thing.isInitialized初始化。< / p>

答案 1 :(得分:1)

所以基本上发生的事情是在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作为起始状态,但随后不可为空)

你可以这样做:

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

希望它有所帮助,如果您有任何其他疑问,请告诉我。