可以在when语句中进行smartCast吗?

  • 本文关键字:smartCast when 语句 kotlin
  • 更新时间 :
  • 英文 :


下面有代码

class Sample {
var variable1: SomeClass? = null
var variable2: SomeClass? = null
var variable3: SomeClass? = null

fun checkVariable() {
when {
variable1 != null -> variable1!!.doSomething()
variable2 != null -> variable2!!.doSomething()
variable3 != null -> variable3!!.doSomething()
}
}
}

我希望我可以使->之后的variableX不可为空,所以我不需要!!。我可以用

避免!!
variable1 !== null -> variable1?.doSomething()

但是有没有更优雅的方法,让我可以有一个非空变量来访问doSomething()?

这个错误不是因为when。你不能智能强制转换类级别的var

在这种情况下,由于所有变量都是相同类型的,并且您对所有变量执行相同的操作,因此您的代码可以简化为:

(variable1 ?: variable2 ?: variable3)?.doSomething()

换句话说,您正在查找三个变量中的第一个非空变量,并对其调用doSomething

如果你的变量不是同一类型的,并且你对每个变量做不同的事情,你可以这样做:

variable1?.also {
it.doSomething()
} ?: variable2?.also {
it.doSomethingElse()
} ?: variable3?.also {
it.doAnotherThing()
}

不知道这样是否更优雅,但你可以这样写:

fun getStrLength() = (variable1 ?: variable2 ?: variable3)?.doSomething()

另一种删除!!的方法是首先将它们存储在局部变量中,如
fun getStrLengths() {

val variable1 = variable1
val variable2 = variable2

val variable3 = variable3
 
when {

variable1 != null -> variable1.doSomething()

variable2 != null -> variable2.doSomething()

variable3 != null -> variable3.doSomething()

}
}

延迟初始化

您可以使用lateinit var将属性设置为非空。

这将防止需要任何空检查。

您可以检查isInitialized是否存在属性,而不是非空检查。

class Sample {
lateinit var variable1: SomeClass
lateinit var variable2: SomeClass
lateinit var variable3: SomeClass
fun checkVariable() {
when {
// so long as a value is initialised, there is no need for null checks
::variable1.isInitialized -> variable1.printName()
::variable2.isInitialized -> variable2.printName()
::variable3.isInitialized -> variable3.printName()
}
}
}
class SomeClass(val name: String) {
fun printName() {
println(name)
}
}

复位值

这对于避免null检查很有用,但它会阻止'unsetting'先前使用null设置的变量。

val sample = Sample()
sample.variable1 = SomeClass("foo")
sample.variable1 = null // ERROR: Null can not be a value of a non-null type SomeClass

是否需要取消设置值取决于您的用例。

fun main() {
val sample = Sample()
println("first check:")
sample.checkVariable()
println("---")
sample.variable3 = SomeClass("Jamie")
println("second check:")
sample.checkVariable()
println("---")
sample.variable2 = SomeClass("Maddie")
println("third check:")
sample.checkVariable()
println("---")
sample.variable1 = SomeClass("Lisa")
println("fourth check:")
sample.checkVariable()
println("---")
}

我们可以看到,当每个变量被设置时,其他变量没有被调用,因为它们在when语句中列在下面。

first check:
---
second check:
Jamie
---
third check:
Maddie
---
fourth check:
Lisa
---

最新更新