丢弃返回值以返回单位?

时间:2017-11-19 16:31:40

标签: kotlin

我刚开始使用kotlin,所以请原谅我,如果这是一个基本问题,我确实做了一些谷歌搜索,但这并没有发现任何有用的东西。

问题是如何将值转换为Unit。 例如,在scala中,如果我写这样的东西:

def foo: Int = ???
def bar(x: String): Unit = x match {
  case "error" => println("There was an error")
  case _ => foo      

}

match表达式的返回类型为Any,但编译器将其丢弃,并且函数返回Unit

但是在kotlin做这样的事情:

fun bar(x: String): Unit = when(x) {
 "error" ->  println("There was an error") 
 else -> foo()
}

它抱怨foo部分:inferred type is Int but Unit was expected

我知道,在这种情况下,我可以摆脱=,然后把身体放在一个块里面,这样可行,但我正在寻找一个通用的解决方案。到目前为止我能够得到的只是foo.let {},但它看起来有点笨拙,特别是如果有很多这样的情况需要完成。

3 个答案:

答案 0 :(得分:5)

你可以create an extension method on Any object and call it。我更喜欢使用名称discard()而不是toUnit(),因为我觉得它的意图更好:

fun Any?.discard() = Unit

fun foo(): Int = 3

fun bar(x: String): Unit = when (x) {
    "error" -> println("There was an error")
    else -> foo().discard()
}

答案 1 :(得分:1)

没有办法开箱即用,但你可以为此做一个扩展功能:

fun Any?.unit() = Unit

然后将其用作:

fun bar(x: String): Unit = when(x) {
    "error" ->  println("There was an error") 
    else -> foo().unit()
}

或者,使when成为一个陈述而不是表达式:

fun bar(x: String) {
    when(x) {
        "error" ->  println("There was an error") 
        else -> foo()
    }
}

答案 2 :(得分:0)

我的脑海中有三种解决方案:

  1. 使when成为语句而不是表达式,因此不会返回其结果:

    fun bar(x: String) {
         when(x) {
            "error" ->  println("There was an error") 
            else -> foo()
        }
    }
    
  2. 使用扩展程序将值转换为Unit

    fun Any?.asUnit() = Unit
    

    用法:

    fun bar(x: String): Unit =
       when (x) {
           "error" -> println("There was an error")
            else -> foo().asUnit()
    }
    
  3. 将调用包含在返回Unit的高阶函数调用中,例如with

    fun bar(x: String): Unit = with(x){
        when (x) {
            "error" -> println("There was an error")
            else -> foo()
        }
    }