说我有以下课程:
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作为起始状态,但随后不可为空)
答案 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
}
}
希望它有所帮助,如果您有任何其他疑问,请告诉我。