Kotlin无效安全的最佳实践

时间:2018-06-05 02:34:07

标签: kotlin kotlin-null-safety

我目前正在学习Kotlin以在我的Android应用程序中替换Java,但我正在努力解决null安全问题。

我熟悉处理null和非null变量的过程,但是,我仍然不确定"最佳实践"就Kotlin中的null /非null变量实现而言。

例如,在Java中我会写一些类似的东西:

UserAccount account;

if (account == null) {
    openLogin();
}

我知道我可以在Kotlin中复制这个,但似乎该语言旨在避免像这样的练习。如果我要添加一个可以为空的变量,我将如何通过Kotlin实现这个系统呢?

3 个答案:

答案 0 :(得分:5)

  

我知道我可以在Kotlin中复制这个内容,但似乎该语言旨在避免像这样的练习。

请注意语言 without nulls null-safe 语言之间的区别。 Kotlin是后者,这意味着它欢迎并接受null值,但是,与Java这样的语言相反,它会带来一条带。

Kotlin为您提供了以简洁,可读和安全的方式处理可空类型的语法。对于你的例子,

if (account == null){
    openLogin();
}

你可以用这个成语:

account ?: openLogin()

在其他时刻,您会想要对非空account采取行动,或者只是跳过代码的null部分。然后你可以使用可选的derefence ?.

account?.userName?.also { println("Username is $it") }

答案 1 :(得分:4)

可能这种材料很有用:http://www.baeldung.com/kotlin-null-safety

您可以搜索let()和run()方法。

  

let()方法

     

仅在引用包含时执行操作   不可为空的值,我们可以使用let运算符。

     

假设我们有一个值列表,并且还有一个空值   在该清单中:

val firstName = "Tom"
val secondName = "Michael" val names:
List<String?> = listOf(firstName, null, secondName)
  

接下来,我们可以使用let函数对名称列表中的每个非可空元素执行操作:

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) }
  

run()方法

     

Kotlin有一个run()方法来执行某些操作   在可空的参考上。它与let()非常相似,但在a里面   函数体,run()方法对此引用进行操作而不是   函数参数:

var res = listOf<String?>()
for (item in names) {
    item?.run{res = res.plus(this)}
}

答案 2 :(得分:2)

  

我知道我可以在Kotlin中复制这个,但似乎该语言旨在避免像这样的练习。

我说恰恰相反,它旨在支持它。例如。如果你有

val account: UserAccount? = ...

if (account == null){
    openLogin()
} else {
    ...
}

编译器知道account分支中的null不是else,并且它可以在那里有效地具有不可为空的UserAccount类型。 (小警告:在您的情况下account更有可能是var,这会对智能广播进行一些限制。)

  

如果我要添加一个可以为空的变量,我将如何通过Kotlin实现此系统?

您没有添加变量,您指定account在其类型中可以为空。

虽然对于这种特殊情况,最好使用lateinit,具体取决于您的要求:

lateinit var account: UserAccount

...
if (!::account.isInitialized) {
    openLogin()
}