Kotlin v2.0.21 Help

空值安全

在 Kotlin 中, null 值是有可能出现的。当某些东西缺失或尚未设置时,Kotlin 就会使用 null 值。 你已经在 集合 章节中看到过 Kotlin 返回 null值的例子,当你尝试访问一个在映射中不存在的键值对时。 虽然以这种方式使用 null 值很有用,但如果你的代码没有准备好处理这些值,你可能会遇到问题。

为了帮助防止程序中出现 null 值问题,Kotlin 提供了 null 安全性。 null 安全性在编译时检测潜在的 null 值问题,而不是在运行时。

null 安全性是一组功能的组合,它允许你:

  • 明确声明在程序中何时允许 null 值。

  • 检查 null 值。

  • 使用安全调用来访问可能包含 null 值的属性或方法。

  • 声明在检测到 null 值时要采取的操作。

可空类型

Kotlin 支持可空类型,这允许声明的类型具有 null 值。 默认情况下,类型 允许接受 null 值。可空类型通过在类型声明后显式添加 ? 来声明。

例如:

fun main() { // neverNull 具有 String 类型 var neverNull: String = "This can't be null" // 会抛出编译错误 neverNull = null // nullable 具有可空 String 类型 var nullable: String? = "You can keep a null here" // 这没问题 nullable = null // 默认情况下,null 值是不被接受的 var inferredNonNull = "The compiler assumes non-nullable" // 会抛出编译错误 inferredNonNull = null // notNull 不接受 null 值 fun strLength(notNull: String): Int { return notNull.length } println(strLength(neverNull)) // 18 println(strLength(nullable)) // 会抛出编译错误 }

检查 null

你可以在条件表达式中检查 null 值的存在。在下面的例子中, describeString() 函数有一个 if 语句,它检查 maybeString 是否 null 并且其 length 是否大于零:

fun describeString(maybeString: String?): String { if (maybeString != null && maybeString.length > 0) { return "String of length ${maybeString.length}" } else { return "Empty or null string" } } fun main() { val nullString: String? = null println(describeString(nullString)) // Empty or null string }

使用安全调用

要安全地访问可能包含 null 值的对象的属性,可以使用安全调用操作符 ?.。 安全调用操作符会在对象或其访问的属性为 null 时返回 null。 这在你想避免 null 值在代码中触发错误时非常有用。

在下面的例子中, lengthString() 函数使用安全调用来返回字符串的长度或 null

fun lengthString(maybeString: String?): Int? = maybeString?.length fun main() { val nullString: String? = null println(lengthString(nullString)) // null }

安全调用操作符也可以用来安全地调用扩展函数或成员函数。 在这种情况下,会在调用函数之前执行 null 检查。如果检查发现 null 值,则跳过调用并返回 null

在下面的例子中, nullStringnull ,因此调用 .uppercase() 被跳过,返回 null

fun main() { val nullString: String? = null println(nullString?.uppercase()) // null }

使用 Elvis 操作符

你可以使用 Elvis 操作符 ?: 提供一个默认值,当检测到 null 值时返回该默认值。

在 Elvis 操作符的左侧写出要检查的 null 值,在右侧写出检测到 null 值时应返回的默认值。

在下面的例子中, nullStringnull ,因此安全调用访问 length 属性返回 null 值。 结果,Elvis 操作符返回 0

fun main() { val nullString: String? = null println(nullString?.length ?: 0) // 0 }

有关 Kotlin 中 null 安全性的更多信息,请参见 空值安全

实践

练习

你有一个 employeeById 函数,它可以访问公司员工的数据库。 不幸的是,这个函数返回 Employee? 类型的值,因此结果可能是 null。 你的目标是编写一个函数,当提供员工的 id 时返回该员工的薪水,如果数据库中缺少该员工,则返回 0

data class Employee (val name: String, var salary: Int) fun employeeById(id: Int) = when(id) { 1 -> Employee("Mary", 20) 2 -> null 3 -> Employee("John", 21) 4 -> Employee("Ann", 23) else -> null } fun salaryById(id: Int) = // 在这里写下你的代码 fun main() { println((1..5).sumOf { id -> salaryById(id) }) }
data class Employee (val name: String, var salary: Int) fun employeeById(id: Int) = when(id) { 1 -> Employee("Mary", 20) 2 -> null 3 -> Employee("John", 21) 4 -> Employee("Ann", 23) else -> null } fun salaryById(id: Int) = employeeById(id)?.salary ?: 0 fun main() { println((1..5).sumOf { id -> salaryById(id) }) }

下一步是什么?

恭喜!现在你已经完成了 Kotlin 之旅,之后请查看我们有关 Kotlin 常用应用的教程:

Last modified: 26 十一月 2024