Kotlin契约能否推断函数所有可变参数的非空性?
Kotlin契约:vararg函数无法推断多参数非空的问题与解决方案探讨
我想实现一个带实验性契约的顶级函数,用来判断传入的任意数量参数中是否包含null:
@ExperimentalContracts fun containsNull(vararg objs: Any?): Boolean { contract { returns(false) implies (/* ???? */) } for (o in objs) if (o == null) return true return false }
期望调用后,后续代码能直接安全访问参数的属性,无需?.操作符,例如:
if (containsNull(value1, value2, value3)) return doSomething(value1.myProperty) /* 多次类似调用,无需安全调用 */
但我发现没法填充implies里的内容——因为vararg参数会被转换成可迭代集合,单个参数的非空信息丢失了,编译器无法知晓所有传入的参数都安全非空。
目前我能想到的两种实现方式:
- 编写多个重载函数,针对不同数量的参数分别声明契约:
@ExperimentalContracts fun containsNull(obj1: Any?, obj2: Any?): Boolean { contract { returns(false) implies (obj1 != null && obj2 != null) } return obj1 == null || obj2 == null } @ExperimentalContracts fun containsNull(obj1: Any?, obj2: Any?, obj3: Any?): Boolean { contract { returns(false) implies (obj1 != null && obj2 != null && obj3 != null) } return obj1 == null || obj2 == null || obj3 == null } /* 更多参数的重载... */
每个重载的契约里明确声明所有参数的非空性。
- 不封装函数,直接用try-catch强制断言非空:
try { value1!! value2!! } catch (e: NullPointerException) { return } doSomething(value1.myProperty)
这种写法比value1 == null || value2 == null || ...的链式判断稍简洁,但还是显得冗余。
我的判断是否正确?有没有更简洁优雅的解决方案?
内容的提问来源于stack exchange,提问作者The Freezing Chicken
相关产品推荐
相关产品推荐

