kotlin - 为什么 check()、require() 和 assert() 不会产生智能转换?
问题描述
考虑以下代码片段:
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
或!!
:
s!!.length
为什么在上面的代码中没有执行智能转换?
解决方案
前段时间我回答了一个有关assert
和之间区别的相关问题require
。TL;DR:assert
不保证会抛出异常,但是require
会。在 1.3 中,它也使用了契约,这意味着如果方法返回,编译器就知道该语句是正确的,如果适用,它可以应用智能转换。
这解释了为什么assert
不这样做;从断言返回并不意味着该陈述是正确的。ea
使用您拥有的代码,除非为真,否则它不会引发异常。即使在 1.3 中,断言也不会触发智能施法。
check
并且require
两者都在 1.3 及更高版本上触发智能转换(由于合同),断言不会(没有合同并且不保证如果条件失败它实际上会引发异常)。
我在 Kotlin 论坛上找到了这篇文章,问你到底是什么人。联系人存在了很长时间,但这篇文章也支持了我最初的假设:虽然联系人存在,但他们还没有准备好。如第二篇文章所述,有效禁用。这就是智能投射不起作用的原因。
然而,在 Kotlin 1.3 中,合约被释放了。如果您升级,您会发现它确实有效(至少对我有效)。
1.3-M2中添加了完整的合同支持,这是 1.3 的预发布版本。
推荐阅读
- python - 更改 3D 网格 vtk 的原点
- pyqtgraph - pyqtgraph:如何链接两个 PlotWidget 窗口以显示相同的绘图?
- c# - 为什么我的嵌套 Webgrid Jquery 无法删除最后一列并预先展开和折叠
- tesseract - Tesseract(瑞典语)无法识别特殊字符,如 @、§ 等
- javascript - 在 C3.JS 中创建一条没有坡度的线
- ios - 为什么 userNotificationCenter didReceive 没有被解雇?
- java - 重绘和 Mouselistener Java
- javascript - 生成无重复的随机元素
- postgresql - 创建触发器更新
- ios - XLPagerTabStrip 将水平滚动选项卡切换到多行选项卡