Контракт Kotlin выводит возвращаемое значение вместо значения аргумента - PullRequest
2 голосов
/ 25 апреля 2019

У меня есть функция, которая выглядит примерно так:

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

В местах, где я знаю, что мой MyInput не равен нулю (например, внутри метода, который принимает input: MyInput в качестве аргумента), я бы хотел использовать input.toOutput в качестве Output вместо Output?

Я пытался использовать

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

Но это имеет значение в обратном направлении. Это говорит мне о том, что если toOutput возвращает ненулевой тип, то мой input был не нулевым. Я хочу рассказать анализатору вещи о возвращаемом значении на основе аргументов. В Java я мог бы использовать org.jetbrains.annotations.@Contract("null -> null ; !null -> !null") для этого.

Есть ли способ сделать это в Котлине?

1 Ответ

4 голосов
/ 25 апреля 2019

Для этого вам не нужны контракты. Вам просто нужно сделать ненулевую перегрузку. Как это:

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)

Вы по-прежнему сможете называть его как input.toOutput() из Kotlin, но он станет чем-то вроде FileNameKt.toOutputNonNull(input), если вы позвоните из Java.

...