Kotlin、空值和双感叹号:初识
\n\n你是否曾在编写 Kotlin 代码时,编译器因潜在的 null 而报错,而你则用两个感叹号 !! 回应,然后继续前行?如果是,那么你已经熟悉了本文的主角——double bang 运算符(也就是 Kotlin 中的 !! 运算符)。
这个符号既是救星,也是危险工具。它告诉编译器:“闭嘴,我知道我在做什么,这个变量绝对不是 null”。但如果你错了——应用程序就会因 NullPointerException 而崩溃。听起来很可怕?实际上,这只是一个强大的机制,需要理解并明智地使用它。
在本指南中,我们将详细解析什么是 double bang Kotlin,它是如何工作的,在何处使用,以及在何处最好寻找替代方案。你将学会如何避免搬起石头砸自己的脚,并编写可靠的代码。
\n\n!! 解决的问题:Kotlin 中的空安全
\n\nKotlin 被设计成一种旨在消灭 NullPointerException (NPE) 的语言。而且它几乎做到了。在 Kotlin 中,类型默认不能为 null。你根本无法将 null 赋值给 String 类型的变量——编译器不允许。
var name: String = "爱丽丝"\nname = null // 编译错误!\n\n\n但现实世界充满了不确定性。数据来自数据库、用户输入和网络。因此,Kotlin 引入了可空类型——可以为 null 的类型。它们用问号表示:String?。
var nullableName: String? = "鲍勃"\nnullableName = null // 现在可以了\n\n\n然后魔法就开始了。你不能直接对可空变量调用方法:
\n\nval length = nullableName.length // 错误!"只允许安全 (?.) 或非空断言 (!!.) 调用"\n\n\nKotlin 强制你处理 null。这很天才——你不会忘记检查。但有时你确切地知道该值不为 null。这时,Kotlin 双感叹号运算符就登场了。
什么是 !!(double bang)运算符?
\n\nKotlin 中的 !! 运算符是一个强制非空断言运算符。它接受一个可空值并将其转换为非空类型。如果该值为 null,则会抛出 KotlinNullPointerException。
语法上,它看起来像变量后面的两个感叹号:
\n\nval nonNullValue = nullableValue!!\n\n示例说明其工作原理
\n\n假设你有一个按 ID 查找用户的函数。它返回 User?,因为用户可能不存在。但你确切地知道在你的测试环境中,ID 为 1 的用户是存在的。
data class User(val name: String)\n\nfun findUser(id: Int): User? {\n // 一些查找逻辑\n return if (id == 1) User("安娜") else null\n}\n\nfun main() {\n val user = findUser(1)\n // 我们确信 user 不为 null\n val userName = user!!.name\n println(userName) // 输出:安娜\n}\n\n\n在这个例子中,double bang Kotlin 正确工作,我们得到了名字。但如果 ID 是 2,应用程序就会因异常而崩溃。
\n\n何时使用 !!(以及何时绝对不能使用)
\n\n!!(double bang)运算符就像一颗红色按钮。你可以按它,但只有在你 146% 确定的时候。让我们分析一下合理的场景。
\n\n何时可以(并且应该)使用 !!
\n\n- \n
- 与 Java 代码交互。 Java 不了解可空注解。如果 Java 方法返回一个对象,Kotlin 会将其视为
Platform Type(例如String!)。你可以随意处理它。但即 \n