我在Kotlin中遇到了一个应该返回Unit的函数的问题,但是由于使用了另一个返回Boolean的函数,所以出现了类型不匹配。
下面是一个人为的例子:
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)
}
}
我确信有一些惯用的方法可以做到这一点(或者是最后一个例子?),但目前我没有找到它们。
7条答案
按热度按时间rqenqsqc1#
不幸的是,没有一个 * 惯用 * 的方法来做这个。一个类似的问题,将
(T) -> Boolean
类型的lambda传递给一个接受(T) -> Unit
lambda的函数,以前已经出现过,并且那里所需要的自动转换应该在将来的某个时候出现在语言中。现在,您可以在
when
表达式的末尾使用扩展函数,将其强制转换回Unit
值:或者,如果您更喜欢扩展属性,也可以使用扩展属性:
当然,如果使用这两种类型中的任何一种,都可以省略函数的显式
Unit
返回类型。t2a7ltrp2#
我认为最后一种是最常用的,虽然你不需要显式的
: Unit
,但如果没有指定返回类型,它是块形式的默认值,如果你试图返回其他类型,你会得到一个错误。但请注意一个微妙的细节:当
when
用作表达式时,除非编译器能够证明所有情况都得到处理,否则else
是必需的;在块形式中,它“用作语句”,未处理的情况将被忽略。r9f1avp53#
作为另一种选择,您可以创建一个更高阶的函数,该函数吞下返回值的函数的输出:
赠送:
6ovsh4lw4#
如果我在一行中书写,我只使用分号。
yjghlzjz5#
我认为你应该把函数的返回类型改为可选,这样更清楚,如下所示:
3htmauhk6#
你也可以这样做
yxyvkwin7#
你可以直接在一个非单位值上调用
.let {}
来丢弃它(同时保留副作用):{}
是一个返回Unit的函数,它忽略了它的参数。let
是一个扩展函数,它将它的接收方传递给给定的lambda --在本例中,lambda忽略它,并根据需要生成Unit。