如何将函数输出转换为Kotlin单元

我在Kotlin函数中遇到麻烦,应该返回Unit,但是由于使用了另一个返回布尔值的函数,会出现types不匹配的情况。

这是一个人为的例子:

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

在这里,我其实并不关心printAndReturnTrue返回一个布尔值的事实。 我只是想让富美执行副作用的操作。 但编译器警告types不匹配:我的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 

或者我使用全function表单:

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

我确信有一些惯用的方法可以做到这一点(或者是最后一个例子?),但是现在我没有find它们。

不幸的是,没有惯用的方法来做到这一点。 一个类似的问题是,将一个(T) -> Booleantypes的lambda传递给一个接受函数(T) -> Unit lambdas的函数已经在之前出现了,并且在那里需要进行自动转换。

现在,您可以在whenexpression式的末尾使用扩展函数将其强制回到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返回types。

我认为最后是最习惯的。 虽然你不需要显式的: Unit ,如果没有指定返回types,它是块forms的默认值,如果你尝试返回别的东西,你会得到一个错误。

但要注意一个细微的细节:当用作expression式时,除非编译器能够certificate所有的情况都被处理, else是必需的。 在块的forms它是“用作一个声明”和未处理的情况下被忽略。

作为另一种选择,您可以创建一个更高阶的函数来吞食返回值的函数的输出:

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

赠送:

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

我认为你应该改变函数的返回types为可选的,更清晰,如下所示:

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