Cómo convertir la salida de la function a la Unidad con Kotlin

Tengo problemas con una function en Kotlin que debería devolver la unidad, pero debido al uso de otra function que devuelve un boolean, hay una discrepancia de tipo.

Aquí hay un ejemplo artificial:

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

Aquí, en realidad no me importa el hecho de que printAndReturnTrue devuelva un boolean. Solo quiero que Foo realice operaciones de efectos secundarios. Pero el comstackdor advierte sobre un desajuste de tipo: mi else debería devolver un valor de Unit .

¿Hay una buena forma de convertir un valor en Unit ?

Las soluciones más simples que veo son:

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

o:

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

O utilizo la forma de function completa:

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

Estoy seguro de que hay algunas forms idiomáticas de hacerlo (¿o es el último ejemplo?), Pero por ahora no las encontré.

    Desafortunadamente, no hay una forma idiomática de hacer esto. Un problema similar, pasando una lambda de tipo (T) -> Boolean a una function que acepta (T) -> Unit lambdas ha aparecido antes, y la conversión automática requerida allí se supone que debe llegar al lenguaje en algún momento futuro.

    Por ahora, puede usar una function de extensión al final de la expresión when para forzarla de nuevo a un valor de Unit :

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

    Alternativamente, una propiedad de extensión, si te gusta más:

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

    Por supuesto, puede omitir el tipo de retorno de Unit explícito de la function si usa cualquiera de estos.

    Creo que el último es más idiomático. Aunque no es necesario : Unit explícita, es la forma pnetworkingeterminada de locking si no se especifica ningún tipo de devolución y si intentas devolver algo más, obtendrás un error.

    Pero tenga en count un detalle sutil: cuando when se usa como expresión, se requiere else , a less que el comstackdor pueda probar que se manejan todos los casos; en el formulario de bloque es "usado como una statement" y los casos no controlados se ignoran.

    Como otra alternativa, puede hacer una function de order superior que trague la salida de la function que devuelve un valor:

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

    Dando:

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

    Creo que deberías cambiar el tipo de devolución de la function a opcional, es más claro, como a continuación:

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