Kotlin 合约推断 return 值而不是参数值

Kotlin contract infer return value instead of argument value

我有一个看起来像这样的函数:

fun MyInput?.toOutput() : Output? {
  if (this == null) return null
  return Output(this.someValue)
}

在我知道我的 MyInput 是非空的地方(例如,在将 input: MyInput 作为 arg 的方法中),我希望能够使用input.toOutput 作为 Output 而不是 Output?

我试过使用

contract {
  returnsNotNull() implies (this@toOutput != null)
}

但这有反面的含义。这告诉我,如果 toOutput return 是一个非空类型,那么我的 input 是非空的。我想根据参数告诉分析器有关 return 值的事情。在 Java 中,我可以使用 org.jetbrains.annotations.@Contract("null -> null ; !null -> !null") 来完成此操作。

有没有办法在 Kotlin 中做到这一点?

你不需要合同。您只需要进行不可为空的重载。像这样:

fun MyInput?.toOutput(): Output? {
  if (this == null) return null
  return Output(this.someValue)
}

fun MyInput.toOutput(): Output = Output(this.someValue)

但是,这在 JVM 上无法开箱即用,因为函数签名会发生冲突。要使其工作,您必须使用 @JvmName 注释为其中一个函数指定一个新名称。例如:

@JvmName("toOutputNonNull")
fun MyInput.toOutput(): Output = Output(this.someValue)

您仍然可以在 Kotlin 中像 input.toOutput() 那样调用它,但如果您在 Java.

中调用它,它将变成类似于 FileNameKt.toOutputNonNull(input) 的东西