为什么不使用check(),require()和assert()进行智能转换?

时间:2018-11-06 13:23:23

标签: kotlin

考虑以下代码片段:

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

!!

为什么上面的代码没有执行智能投射?

1 个答案:

答案 0 :(得分:1)

不久前,我就assertrequire之间的区别回答了related question。 TL; DR:assert不保证会引发异常,但require是。在1.3中,它还使用协定,这意味着如果该方法返回,则编译器知道该语句正确,并且可以在适用的情况下应用智能强制转换。

这说明了assert不这样做的原因;从断言中返回并不会表示该陈述是正确的。使用您拥有的代码,除非ea为true,否则它不会引发异常。断言即使使用1.3,也不会触发智能投射。

checkrequire都在1.3及更高版本上触发智能强制转换(由于合同),assert则没有(没有合同,也不能保证条件失败时实际上会引发异常)。

我在Kotlin论坛上发现了this个帖子,询问您的确切身份。联系人已经存在了很长时间,但是this帖子也支持了我最初的假设:当联系人存在时,他们还没有准备好。如第二篇文章所述,有效禁用。这就是为什么智能投射无法正常工作的原因。

但是,在Kotlin 1.3中,合同已被释放。如果升级,您会看到它确实有效(至少对我有用)。


1.3-M2中添加了完整的合同支持,它是1.3的预发行版。