You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:40:48