Kotlin:若字符串为null,并且使用了双bang(!!)运算符,为什么它会给出长度函数的编译错误?

Kotlin:若字符串为null,并且使用了双bang(!!)运算符,为什么它会给出长度函数的编译错误?,kotlin,compiler-errors,string-length,non-nullable,kotlin-null-safety,Kotlin,Compiler Errors,String Length,Non Nullable,Kotlin Null Safety,例如: 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 use

例如:

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


注:我是Kotlin的新手。

如果左侧的计算结果为
null
,操作员就会短路。因此
nullVariable?.length
的结果是
null
,而
.length
永远不会被计算。您的第一个示例是有效地执行以下操作:

println("Length of the string is :" + null)
操作符说“如果左侧为null,则抛出一个
NullPointerException
。否则,我们知道右侧不是null”。如果稍微更改第二个示例,您可以看到:

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

但是,我不确定您为什么会得到
未解析的引用:length
。当您将
null
直接分配给
userInput
时,编译器似乎正在进行一些优化,因此,与其将其编译为运行时抛出NPE的
String?
,还不如知道编译时的值仅为
null
(不是
String?
),因此不能具有
length
属性,因为
null
不是引用

您可以通过函数调用添加抽象层,强制它为您提供
NullPointerException

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

fun alwaysNull(): String? = null

我在文档中没有看到任何关于在一行中初始化/通过函数调用初始化与直接将
null
分配给var之间行为差异的内容,因此,引擎盖下发生的获取
未解析引用的情况只是猜测。

?。
如果左侧的计算结果为
null
,则操作员短路。因此
nullVariable?.length
的结果是
null
,而
.length
永远不会被计算。您的第一个示例是有效地执行以下操作:

println("Length of the string is :" + null)
操作符说“如果左侧为null,则抛出一个
NullPointerException
。否则,我们知道右侧不是null”。如果稍微更改第二个示例,您可以看到:

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

但是,我不确定您为什么会得到
未解析的引用:length
。当您将
null
直接分配给
userInput
时,编译器似乎正在进行一些优化,因此,与其将其编译为运行时抛出NPE的
String?
,还不如知道编译时的值仅为
null
(不是
String?
),因此不能具有
length
属性,因为
null
不是引用

您可以通过函数调用添加抽象层,强制它为您提供
NullPointerException

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

fun alwaysNull(): String? = null
但是,我在文档中没有看到关于在一行中初始化/通过函数调用初始化与直接将
null
分配给var之间行为差异的任何内容,因此,在引擎盖下发生的获取
未解析引用的情况只是一个猜测