1

例子:

fun main(){
    var userInput: String?
    //userInput = null
    userInput = "asbdef"
    var inputLength:Int? = userInput!!.length
    println("Length of the string is :"+inputLength)
}

输出:字符串的长度为:6

fun main(){
    var userInput: String?
    userInput = null
    //userInput = "asbdef"
    var inputLength:Int? = userInput!!.length
    println("Length of the string is :"+inputLength)
}

输出:未解决的参考:长度

我想知道为什么它会产生编译错误?

如果我只是用 (?) 替换 (!!) 运算符,它编译得很好,但将输出打印为 null。

PS:我是 Kotlin 的新手

4

1 回答 1

0

?.如果左侧计算结果为 ,则运算符短路null。所以nullVariable?.lengthisnull的结果.length永远不会被评估。你的第一个例子是有效地做:

println("Length of the string is :" + null)

!!运算符说“如果左侧为空,则抛出 a 。NullPointerException否则,我们知道右侧不为空”。如果您稍微更改第二个示例,您可以看到这一点:

val userInput: String? = null
val inputLength:Int = userInput!!.length // throws NullPointerException

但是,我不确定你为什么会得到Unresolved reference: length. null当您直接分配给时,编译器似乎正在做一些优化userInput,因此它不会将其编译为String?在运行时抛出 NPE,而是在编译时知道该值仅是null(不是String?),因此不能拥有length属性,因为null不是参考。

NullPointerException您可以通过函数调用添加抽象层来强制它给您:

fun main(){
    var userInput: String? = "foo"
    userInput = alwaysNull()
    val inputLength:Int = userInput!!.length // NullPointerException
}

fun alwaysNull(): String? = null

我在Null Safety文档中没有看到任何关于在一行中初始化/通过函数调用与null直接分配给 var 之间的行为差​​异的任何内容,所以在后台发生的事情Unresolved reference只是一个猜测。

于 2020-10-11T15:46:19.370 回答