浅谈Kotlin编程-Kotlin空值处理
前言
许多编程语⾔(包括 Java)中最常⻅的错误之⼀,就是访问空成员会导致空异常(NullPointerException 或简称 NPE)。
开发中,经常会遇到空指针异常,如果对这个问题处理不当,还会引起程序的崩溃(crash),在Kotlin中,为了避免出现空指针异常,引入了 Null机制,本篇就来了解一下Kotlin中的 Null机制。
本文总览
1. 可空类型变量(?)
Kotlin中把变量分成了两种类型
- 可空类型变量
- 非空类型变量
通常,一个变量默认是非空类型。若要变量的值可以为空,必须在声明处的数据类型后添加 ?
来标识该变量可为空。如下示例:
var phone: String //声明非空变量
var price: Int? //声明可空变量
上述代码中,phone 为非空变量,price 为可空变量。若给变量name赋值为null,编译器会提示“Null can not be a value of a non-null type String”
错误信息。引起这个错误的原因是Kotlin官方约定变量默认为非空类型时,该变量不能赋值为null, 而price 赋值为null,编译可以通过。
声明可空变量时,若不知道初始值,则需将其赋值为null,否则会报“variable price must be initialized”
异常信息。
通过一段示例代码来学习如何判断变量是否为空,以及如何使用可空变量:
fun main() {
var name: String = "Any" // 非空变量
var phone: String? = null // 可空变量
if (phone != null) {
print(phone.length)
} else {
phone = "12345678901"
print("phone = " + phone)
}
}
运行结果:
phone = 12345678901
上述代码,定义一个非空变量 name,一个可空变量 phone。这段示例代码对可空变量进行判断,如果 phone 不为空则输出 phone的长度,否则将phone赋值为12345678901并打印输出。
2. 安全调用符(?.)
上一点的示例中,可空变量在使用时需要先通过if…else
判断,然后再进行相应的操作,这样使用还是比较繁琐。Kotlin提供了一个安全调用符?.
,用于调用可空类型变量中的成员方法或属性,语法格式为“变量?.成员”。其作用是先判断变量是否为null,如果不为null才调用变量的成员方法或者属性。
fun main() {
var name: String = "Any"
var phone: String? = null
var result = phone?.length
println(result)
}
运行结果:
null
结果可以看出,在使用?.
调用可空变量的属性时,若当前变量为空,则程序编译正常运行,且返回一个null值。
3. Elvis操作符(?:)
安全调用符调用可空变量中的成员方法或属性时,如果当前变量为空,则返回一个null值,但有时不想返回一个null值而是指定一个默认值,该如何处理呢?Kotlin中提供了一个Elvis操作符(?:)
,通过Elvis操作符(?:)
可以指定可空变量为null时,调用该变量中的成员方法或属性的返回值,其语法格式为 表达式 ?: 表达式 。若左边表达式非空,则返回左边表达式的值,否则返回右边表达式的值。
fun main() {
var name: String = "Any"
var phone: String? = null
var result = phone?.length ?: "12345678901"
println(result)
}
运行结果:
12345678901
从结果可以看出,当变量phone为空时,使用?:
操作符会返回指定的默认值“12345678901”,而非null值。
4. 非空断言(!!.)
除了使用安全调用符(?.)
来使用可空类型的变量之外,还可以通过非空断言(!!.)
来调用可空类型变量的成员方法或属性。使用非空断言时,调用变量成员方法或属性的语法结构为 “变量!!.成员” 。非空断言(!!.)
会将任何变量(可空类型变量或者非空类型变量)转换为非空类型的变量,若该变量为空则抛出异常。接下来我们通过一个例子来演示非空断言(!!.)
的使用,具体代码如下所示。
fun main() {
var phone: String? = null // 声明可空类型变量
var result = phone!!.length // 使用非空断言
println(result)
}
运行结果:
Exception in thread"main"kotlin.KotlinNullPointerException
at NoEmptyAssertionKt.main
(NoEmptyAssertion.kt:4)
运行结果抛出了空指针异常,若变量phone赋值不为空,则程序可以正常运行。
安全调用符与非空断言运算符都可以调用可空变量的方法,但是在使用时有一定的差别,如表所示。
操作符 | 安全 | 是否推荐 |
---|---|---|
安全调用符(?.) | 当变量值为null时,不会抛出异常,更安全 | 推荐使用 |
非空断言(!!) | 当变量值为null时,会抛出异常,不安全 | 可空类型变量经过非空断言后,这个变量变为非空变量,非空变量为null时,会报异常,不推荐 |
总结
上面四种情况的介绍,可以说的很全面地囊括 kotlin 中的空处理情况,开发中应根据实际场景使用合适的操作符。
作者:南巷羽
链接:https://juejin.cn/post/7134636916514750495
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。