How to convert function output to Unit with Kotlin

前端 未结 6 410
轻奢々
轻奢々 2021-01-12 11:48

I have troubles with a function in Kotlin that should return Unit, but due to a usage of another function returning a Boolean, there is a type mismatch.

Here is a co

相关标签:
6条回答
  • 2021-01-12 12:06

    You could also do something like

    fun foo(bar: Int): Unit = when(bar) {
        0 -> println("0")
        else -> printAndReturnTrue(bar).let{ Unit }
    }
    
    0 讨论(0)
  • 2021-01-12 12:09

    I think you should change return type of function to optional, it's more clear, like below:

    fun printAndReturnTrue(bar: Int): Boolean {
        println(bar)
        return true
    }
    
    fun foo(bar: Int): Unit? = when(bar) {
        0 -> println("0")
        else -> printAndReturnTrue(bar) as? Unit
    }
    
    0 讨论(0)
  • 2021-01-12 12:12

    Unfortunaly, there's no idiomatic way to do this. A similiar problem, passing a lambda of type (T) -> Boolean to a function accepting (T) -> Unit lambdas has come up before, and the auto conversion required there is supposed to come to the language at some future point.

    For now, you could use an extension function at the end of the when expression to coerce it back into a Unit value:

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

    Alternatively, an extension property, if you happen to like that better:

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

    Of course you can omit the explicit Unit return type of the function if you use either of these.

    0 讨论(0)
  • 2021-01-12 12:21

    As another alternative, you could make a higher order function that swallows the output of the function returning a value:

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

    Giving:

    fun foo(bar: Int): Unit = when(bar) {
        0 -> println("0")
        else -> consume { printAndReturnTrue(bar) }
    }
    
    0 讨论(0)
  • 2021-01-12 12:27

    I think the last is most idiomatic. Though you don't need explicit : Unit, it's the default for block form if no return type is specified and if you try to return something else you'll get an error.

    But note a subtle detail: when when is used as an expression, else is required unless the compiler can prove all cases are handled; in the block form it's "used as a statement" and unhandled cases are ignored.

    0 讨论(0)
  • 2021-01-12 12:28

    I just use a semicolon if I write in a line.

    someExpression; Unit
    
    0 讨论(0)
提交回复
热议问题