“?”在 Kotlin 变量中……这样做的目的是什么?

" ? " in Kotlin Variable.. what's the purpose on this?

我正在学习用于 Android 开发的 Kotlin 语言基础知识 :),我正在查看一些 Kotlin 语法示例,我在下面找到了这个示例。我不知道 ? 代码的目的是什么.. 我试图在 Google 上找到但我不能完全理解他们解释的内容,也许你可以帮忙我对你的解释/你的例子?我会很感激:)

示例:

fun main() {

    val myName :String? = "Maura"
    println("Your name is $myName")

    val myAge :Int? = 18
    println("Your age is $myAge")

}

好吧,这是 Kotlin lang 的 null safety feature(顺便说一句,很棒。)

简而言之:variable/value 类型旁边的 ? 表示此 variable/value 可能是 null。不要经常使用它,它可以保护您免受 NullPointerException 的影响,通常是 Java 中的错误原因。同样在您的简单情况下,这是不必要的

var myName :String? = null // this is possible
var mySecondName :String = null // this isn't possible, build error

var myThirdName :String = "never null"
myThirdName = null // build error, this variable can't be null

myName = myName.replace("a", "b")
// build error above, trying to access nullable variable straightly
myName = myName?.replace("a", "b")
// null safety with ?, if myName is null it won't be executed and myName stay null

myThirdName = myThirdName.replace("a", "b") // this is possible
myThirdName = myThirdName?.replace("a", "b")
// this is also possible, but you will get a warning that ? is unnecessary

它是零安全。基本上 Int? 表示可为空的 Int,而 Int 本身是非空的。

var a: Int = 5
a = null  // error

var b: Int? = 5
a = null  // :)

如果你的代码中有 null,你不能直接使用它们,例如,如果你想调用其中的任何函数,你必须遵循 null-safety:使用 ?. safecall运算符,或 !!. 空断言运算符(通常不应使用)。

val c = a.plus(4)  // :)
val d = b.plus(4)  // Hold on, I'm null you can't use "." on me :P

val e = b?.plus(4)  // Ok, if b is not null, add 4 and store that to e, otherwise store null to e
val f = b!!.plus(4)  // Hmm, if b was not null I'll add 4 to it and store to f, otherwise I'll crash your program throwing NPE

与此相反,e 的类型将是 Int?,因为您已经阅读过该内容。但是如果你想给它分配一个默认值呢,很容易使用 elvis 运算符 (?:):

val g = b?.plus(4) ?: 4  // if b is not null add 4 to it and store otherwise store 4 :)

编辑: 您的示例中的代码之所以有效,是因为存在字符串模板调用 .toString() 并且它被定义为 fun Any?.toString(),即在可为空的接收器上定义。所以 b.toString 是有效的,尽管可能会造成混淆。

println("Your age is $myAge")

// is same as
println("Your age is" + myAge.toString())

// toString is an extension function valid for nullable types, though member functions aren't :)