Kotlin契约
Contract
Contract的中文叫做协议,协约,合同。
这个合同呢是和编译器签订的。
kotlin的编译器比较聪明但是不是太聪明。
所以有的时候会犯傻hh。
引入Contract
比如这同样。
ensureNotNullAndEmpty已经确定了str不为空,也不为””
但是使用的时候编译器还是认为这个东西可能是空的。
如果这个时候我们想告诉编译器这个东西不是空的,那该怎么弄。
这就得使用contract了
很简单就修改一下代码
1 |
|
这样就不报错了
Contract使用
Contract内部的内容比较少
- returns()
- returnsNotNull()
- callsInPlace()
前两个就不做过多解释
第三个是告诉编译器这个函数会在在函数作用域内部执行几次
比如run
1 | public inline fun <R> run(block: () -> R): R { |
也就是说在执行run这个内联函数期间,block会被调用一次。
这有啥用?
当然有用
1 | fun main() { |
这个代码编译会报错嘛?
答案是不会。
因为编译器知道lambda会被调用一次,所以不存在Val cannot be reassigned的报错。
如果去除这个contract你会发现报错了。
Contract的注意事项
不知道你是否有类似的想法。
我告诉编译器这个block会被调用一次,但是我在内部调用了多次,欸就是玩。我不遵循Contract欸。编译器会报错吗?
1 | fun main() { |
会发现编译器正常执行了两次。
没有报错欸。
执行结果
嘿嘿
嘿嘿
那如果这样呢
1 | fun main() { |
欸,编译通过了。
run一下
很奇怪没报错
当前 x的值 false
当前 x的值 false
再改一下
1 | fun main() { |
并不会,所以这个Contract只是告诉编译器。编译器知道了以后,以前不能编译通过的代码可以通过了,但是如果运行时期出问题了那也没办法。这不是编译器的问题,所以使用Contract得注意。你不遵循编译器并不会报错。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 理想三巡!