考虑以下代码片段:
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
}
}
Run Code Online (Sandbox Code Playgroud)
虽然check()
和require()
都有
contract {
returns() implies value
}
Run Code Online (Sandbox Code Playgroud)
在他们的体内,上面的代码仍然无法编译,迫使我使用?.
:
s?.length
Run Code Online (Sandbox Code Playgroud)
或者!!
:
s!!.length
Run Code Online (Sandbox Code Playgroud)
为什么上面的代码中没有执行智能转换?
我不久前回答过一个相关问题,assert
关于和之间的区别require
。TL;DR:assert
不能保证抛出异常,但require
确实会抛出异常。在 Kotlin 1.3 中,它还使用契约,这意味着如果方法返回,编译器就知道该语句是正确的,并且可以应用智能转换(如果适用)。
这解释了为什么assert
不这样做;从断言返回并不意味着该陈述是正确的。使用您拥有的代码,除非为真,否则它不会抛出异常ea
。即使使用 1.3,断言也不会触发智能转换。
check
并且require
两者都会在 1.3 及更高版本上触发智能转换(因为合约),而断言则不会(没有合约,并且不能保证如果条件失败它实际上会抛出异常)。
我在 Kotlin 论坛上找到了这篇文章,询问您到底是什么。这些合同已经存在了相当长的一段时间,但这篇文章也支持了我最初的假设:虽然合同已经存在,但它们还没有准备好。正如第二篇文章提到的那样,实际上已被禁用。这就是智能转换不起作用的原因。
然而,在 Kotlin 1.3 中,合约被发布了。如果您升级,您会发现它确实有效(至少对我来说是这样)。
1.3-M2中添加了完整的合约支持,它是 1.3 的预发布版本。
归档时间: |
|
查看次数: |
978 次 |
最近记录: |