Я думаю, вы должны изменить тип возвращаемого значения на необязательный, это более понятно, как показано ниже:

я проблемы с функцией в Kotlin, которая должна возвращать Unit, но из-за использования другой функции, возвращающей логическое значение, существует несоответствие типов.

Вот надуманный пример:

fun printAndReturnTrue(bar: Int): Boolean {
    println(bar)
    return true
}

fun foo(bar: Int): Unit = when(bar) {
    0 -> println("0")
    else -> printAndReturnTrue(bar)
}

Здесь мне на самом деле все равно, чтоprintAndReturnTrue возвращает логическое значение. Я просто хочу, чтобы foo выполняла побочные эффекты. Но компилятор предупреждает о несоответствии типов: мойelse должен вернутьUnit стоимость.

Есть ли хороший способ конвертировать значение вUnit?

Самые простые решения, которые я вижу:

fun foo(bar: Int): Unit = when(bar) {
    0 -> println("0")
    else -> { 
        printAndReturnTrue(bar)
        Unit
    }
}

или же:

fun foo(bar: Int): Unit = when(bar) {
    0 -> println("0")
    else -> eraseReturnValue(printAndReturnTrue(bar))
}

fun eraseReturnValue(value: Any) = Unit

Или я использую полнофункциональную форму:

fun foo(bar: Int): Unit { 
    when(bar) {
        0 -> println("0")
        else -> printAndReturnTrue(bar)
    }
}

Я уверен, что есть некоторые идиоматические способы сделать это (или это последний пример?), Но пока я их не нашел.

Ответы на вопрос(4)

вы должны изменить тип возвращаемого значения на необязательный, это более понятно, как показано ниже:

fun printAndReturnTrue(bar: Int): Boolean {
    println(bar)
    return true
}

fun foo(bar: Int): Unit? = when(bar) {
    0 -> println("0")
    else -> printAndReturnTrue(bar) as? Unit
}

: Unitэто форма по умолчанию для блочной формы, если тип возврата не указан, и если вы попытаетесь вернуть что-то еще, вы получите ошибку.

Но обратите внимание на тонкую деталь: когдаwhen используется в качестве выражения,else требуется, если компилятор не может доказать, что все случаи обработаны; в блочной форме это «используется как утверждение», а необработанные случаи игнорируются.

о порядка, которая поглощает выходные данные функции, возвращающей значение:

fun consume (fn: () -> Any): Unit {
  fn()
}

Предоставление:

fun foo(bar: Int): Unit = when(bar) {
    0 -> println("0")
    else -> consume { printAndReturnTrue(bar) }
}
 Ondřej Fischer11 янв. 2019 г., 21:11
Для лучшей читаемости метод может быть названtoUnit, Может даже принимать значение, а не лямбда:fun toUnit(value: Any?): Unit {} и использование:else -> toUnit(printAndReturnTrue(bar))

идиоматический способ сделать это. Аналогичная проблема, проходящая лямбда типа(T) -> Boolean к функции, принимающей(T) -> Unit Лямбда возникла раньше, и требуемое там автоматическое преобразование должно появиться в будущем.

Сейчас вы можете использовать функцию расширения в концеwhen выражение, чтобы заставить его обратно вUnit стоимость:

fun Any?.toUnit() = Unit

fun foo(bar: Int): Unit = when(bar) {
    0 -> println("0")
    else -> printAndReturnTrue(bar)
}.toUnit()

В качестве альтернативы, свойство расширения, если вам так больше нравится:

val Any?.unit get() = Unit

fun foo(bar: Int): Unit = when(bar) {
    0 -> println("0")
    else -> printAndReturnTrue(bar)
}.unit

Конечно, вы можете опустить явноеUnit вернуть тип функции, если вы используете любой из них.

 Vincent Hiribarren18 нояб. 2017 г., 22:21
Очень хороший другой пример с лямбда-типом. В запоздалой мысли я подумал, что использование версии «=» было не очень хорошим способом, но, похоже, есть и другие допустимые случаи, когда это может быть проблемой.

Ваш ответ на вопрос