I have a function that looks something like:
fun MyInput?.toOutput() : Output? {
if (this == null) return null
return Output(this.someValue)
}
In places where I know that my MyInput is non-null (for example, inside a method that takes a input: MyInput as an arg), I'd like to be able to use input.toOutput as Output instead of Output?
I've tried using
contract {
returnsNotNull() implies (this@toOutput != null)
}
But that has the implication backwards. That tells me that if toOutput returns a non-null type, that my input was non-null. I want to tell the analyzer things about the return value based on the arguments. In Java, I could use org.jetbrains.annotations.@Contract("null -> null ; !null -> !null") to accomplish this.
Is there a way to do this in Kotlin?
You don't need contracts for this. You just need to make a non-nullable overload. Like this:
fun MyInput?.toOutput(): Output? {
if (this == null) return null
return Output(this.someValue)
}
fun MyInput.toOutput(): Output = Output(this.someValue)
However, this will not work out of the box on the JVM, because the function signatures will clash. To make it work, you have to give one of the functions a new name with the @JvmName annotation. For example:
@JvmName("toOutputNonNull")
fun MyInput.toOutput(): Output = Output(this.someValue)
You will still be able to call it like input.toOutput() from Kotlin, but it will become something like FileNameKt.toOutputNonNull(input) if you call it from Java.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With