这个kotlin代码:
socket.io-client-swift
无法使用消息编译:{{1}}
但如果我添加fun badKotlin(text: String?): Boolean {
if (text == null) {
return true
}
var temp = text
if (false) {
temp = Arrays.deepToString(arrayOf(text))
}
return temp.isBlank() // <-- only safe (?.) or non null asserted (!!.) calls
}
:
only safe (?.) or non null asserted (!!.) calls are allowed on a nullable receiver of type String?
全部编译。那么,为什么类型推理失败了?
如果我将温度类型更改为else
,则会成功复制!所以,此外,如果我们像这样更改临时赋值:fun badKotlin(text: String?): Boolean {
if (text == null) {
return true
}
var temp = text
if (false) {
temp = Arrays.deepToString(arrayOf(text))
} else {
temp = Arrays.deepToString(arrayOf(text))
}
return temp.isBlank()
}
它也被编译。
更新:
成功应对:
var temp: String = text
而且:
temp = String.format("%s", text)
答案 0 :(得分:2)
你可能会想到
之后if (text == null) {
return true
}
text
的类型被细化为String
而不是String?
。
但似乎不是;相反,当编译器在需要text
的情况下使用String
时,编译器会插入智能强制转换。在
var temp = text
行没有理由插入强制转换,因此编译器没有,temp
的类型为String?
。
如果你写
var temp: String = text
必须使用 ,因此编译器会插入它。
如果你写
if (...) {
temp = Arrays.deepToString(arrayOf(text))
} else {
temp = Arrays.deepToString(arrayOf(text))
}
编译器发现无论发生什么,temp
都被分配了platform type String!
的值,再次可以智能转换为String
。没有else
分支,就不会发生这种情况。
编辑:
奇怪的是,如果你只是删除if
并离开
fun badKotlin(text: String?): Boolean {
if (text == null) {
return true
}
var temp = text
return temp.isBlank()
}
它确实编译,如果我的解释完成,我不会指望它。因此编译器会保留智能投射所需的信息,但似乎没有应用,因为
更具体地说,智能演员表适用于以下规则:...
var
局部变量 - 如果在检查和使用之间未修改变量,则不会在修改它的lambda中捕获,并且不是本地委托属性; < / LI>
在if-else
案例中,两个分支中的分配一起作为另一个检查;仅在if
- 中,一个分支没有。
答案 1 :(得分:1)
通过将text
分配给temp
,临时类型也会变为String?
。像这样:
var temp: String? = text
由于您的if (false)
永远不会被执行,因此对代码没有任何影响。 else
添加一个始终执行的块(因为它基本上意味着if (true)
)并将String
分配给不可为空的temp
。由于在第二个示例中temp不可为空,因此您不必再使用安全调用操作符...