Kotlin 中空安全的最佳实践
Best practice for null safety in Kotlin
我目前正在学习 Kotlin 来替换我的 android 应用程序中的 Java,但我正在努力解决 null 安全问题。
我已经熟悉了处理空变量和非空变量的过程,但是,在 Kotlin 中实现 null/non-null 变量方面,我仍然不确定 "best practice"。
例如,在 Java 中我会这样写:
UserAccount account;
if (account == null) {
openLogin();
}
我知道我可以在 Kotlin 中复制它,但似乎该语言旨在避免这样的做法。我将如何通过 Kotlin 实现这个系统,我应该添加一个可为 null 的变量吗?
这个 material 可能有用:http://www.baeldung.com/kotlin-null-safety
您可以搜索 let() 和 运行() 方法。
The let() method
To execute an action only when a reference holds a
non-nullable value, we can use a let operator.
Let’s say that we have a list of values and there is also a null value
in that list:
val firstName = "Tom"
val secondName = "Michael" val names:
List<String?> = listOf(firstName, null, secondName)
Next, we can execute an action on every non-nullable element of the names list by using a let function:
var res = listOf<String?>() for (item in names) {
item?.let { res = res.plus(it) } }
assertEquals(2, res.size)
assertTrue { res.contains(firstName) }
assertTrue { res.contains(secondName) }
The run() method
Kotlin has a run() method to execute some operation
on a nullable reference. It is very similar to let() but inside of a
function body, the run() method operates on this reference instead of
a function parameter:
var res = listOf<String?>()
for (item in names) {
item?.run{res = res.plus(this)}
}
I understand I can replicate this in Kotlin but it seems as though the language is designed to avoid practice like this.
请注意无空语言和空安全语言之间的区别。 Kotlin 是后者,这意味着它欢迎并接受 null
值,但是,与 Java 这样的语言相反,它对其施加了约束。
Kotlin 为您提供了以简洁、可读和安全的方式处理可空类型的语法。例如,
if (account == null){
openLogin();
}
你可以使用这个成语:
account ?: openLogin()
在其他时候,您可能想要对非空值 account
执行操作,或者如果它是 null
则跳过该部分代码。然后你可以使用可选的取消引用 ?.
:
account?.userName?.also { println("Username is $it") }
I understand I can replicate this in Kotlin but it seems as though the language is designed to avoid practice like this.
我会说恰恰相反,它旨在支持它。例如。如果你有
val account: UserAccount? = ...
if (account == null){
openLogin()
} else {
...
}
编译器知道 account
不是 else
分支中的 null
,并且它可以在那里有效地具有不可空的 UserAccount
类型。 (小警告:在你的情况下 account
更可能是 var
,这对智能转换有一些限制。)
How would I go about implementing this system through Kotlin, should I be adding a nullable variable?
您没有添加 变量,您指定account
在其类型中可以为空。
尽管对于这种特定情况,使用 lateinit
可能更好,具体取决于您的要求:
lateinit var account: UserAccount
...
if (!::account.isInitialized) {
openLogin()
}
我目前正在学习 Kotlin 来替换我的 android 应用程序中的 Java,但我正在努力解决 null 安全问题。
我已经熟悉了处理空变量和非空变量的过程,但是,在 Kotlin 中实现 null/non-null 变量方面,我仍然不确定 "best practice"。
例如,在 Java 中我会这样写:
UserAccount account;
if (account == null) {
openLogin();
}
我知道我可以在 Kotlin 中复制它,但似乎该语言旨在避免这样的做法。我将如何通过 Kotlin 实现这个系统,我应该添加一个可为 null 的变量吗?
这个 material 可能有用:http://www.baeldung.com/kotlin-null-safety
您可以搜索 let() 和 运行() 方法。
The let() method
To execute an action only when a reference holds a non-nullable value, we can use a let operator.
Let’s say that we have a list of values and there is also a null value in that list:
val firstName = "Tom"
val secondName = "Michael" val names:
List<String?> = listOf(firstName, null, secondName)
Next, we can execute an action on every non-nullable element of the names list by using a let function:
var res = listOf<String?>() for (item in names) {
item?.let { res = res.plus(it) } }
assertEquals(2, res.size)
assertTrue { res.contains(firstName) }
assertTrue { res.contains(secondName) }
The run() method
Kotlin has a run() method to execute some operation on a nullable reference. It is very similar to let() but inside of a function body, the run() method operates on this reference instead of a function parameter:
var res = listOf<String?>()
for (item in names) {
item?.run{res = res.plus(this)}
}
I understand I can replicate this in Kotlin but it seems as though the language is designed to avoid practice like this.
请注意无空语言和空安全语言之间的区别。 Kotlin 是后者,这意味着它欢迎并接受 null
值,但是,与 Java 这样的语言相反,它对其施加了约束。
Kotlin 为您提供了以简洁、可读和安全的方式处理可空类型的语法。例如,
if (account == null){
openLogin();
}
你可以使用这个成语:
account ?: openLogin()
在其他时候,您可能想要对非空值 account
执行操作,或者如果它是 null
则跳过该部分代码。然后你可以使用可选的取消引用 ?.
:
account?.userName?.also { println("Username is $it") }
I understand I can replicate this in Kotlin but it seems as though the language is designed to avoid practice like this.
我会说恰恰相反,它旨在支持它。例如。如果你有
val account: UserAccount? = ...
if (account == null){
openLogin()
} else {
...
}
编译器知道 account
不是 else
分支中的 null
,并且它可以在那里有效地具有不可空的 UserAccount
类型。 (小警告:在你的情况下 account
更可能是 var
,这对智能转换有一些限制。)
How would I go about implementing this system through Kotlin, should I be adding a nullable variable?
您没有添加 变量,您指定account
在其类型中可以为空。
尽管对于这种特定情况,使用 lateinit
可能更好,具体取决于您的要求:
lateinit var account: UserAccount
...
if (!::account.isInitialized) {
openLogin()
}