考虑以下代码片段:
searchResult.Properties["sAMAccountName"][0]
object C {
@JvmStatic
fun main(vararg args: String) {
val s: String? = null
check(s != null) {
"The string is null"
}
require(s != null) {
"The string is null"
}
assert(s != null) {
"The string is null"
}
s.length
}
}
和check()
都拥有
require()
在他们身上,上面的代码仍然没有编译,迫使我使用contract {
returns() implies value
}
:
?.
或s?.length
:
!!
为什么上面的代码没有执行智能投射?
答案 0 :(得分:1)
不久前,我就assert
和require
之间的区别回答了related question。 TL; DR:assert
不保证会引发异常,但require
是。在1.3中,它还使用协定,这意味着如果该方法返回,则编译器知道该语句正确,并且可以在适用的情况下应用智能强制转换。
这说明了assert
不这样做的原因;从断言中返回并不会不表示该陈述是正确的。使用您拥有的代码,除非ea
为true,否则它不会引发异常。断言即使使用1.3,也不会触发智能投射。
check
和require
都在1.3及更高版本上触发智能强制转换(由于合同),assert则没有(没有合同,也不能保证条件失败时实际上会引发异常)。
我在Kotlin论坛上发现了this个帖子,询问您的确切身份。联系人已经存在了很长时间,但是this帖子也支持了我最初的假设:当联系人存在时,他们还没有准备好。如第二篇文章所述,有效禁用。这就是为什么智能投射无法正常工作的原因。
但是,在Kotlin 1.3中,合同已被释放。如果升级,您会看到它确实有效(至少对我有用)。
在1.3-M2中添加了完整的合同支持,它是1.3的预发行版。