使用主题时,科特林的“何时”表达是否支持多种条件?

时间:2018-09-28 02:30:08

标签: kotlin

使用when(subject) { ... }表达式时是否可以提供多个布尔条件?

以下内容不会编译

val num: Any = 2
when(num) {
    // uses implicit subject in addition to an unrelated condition
    is Number && true -> println("TRUE")
    else -> println("FALSE")
}

以下内容将编译,但结果为FALSE。这是预期的行为吗?

val num: Any = 2
when(num) {
    num is Number && true -> println("TRUE")
    else -> println("FALSE")
}

我有很长的 when 条件列表,其中大多数仅使用隐式主题,但是有一些需要次要条件

4 个答案:

答案 0 :(得分:2)

关于第一个:查看when grammar。直接只允许inis(及其否定对等物)。否则,您只有表达式。

现在,关于第二个语句,可能会有助于将其首先转换为if / else语句。基本上,您的when如下所示:

if (num == ((num is Number) && true)) println("TRUE")
else println("FALSE")

如果查看此内容,将会清楚为什么总是打印FALSE。当num is Number变成true并且true && true仍然是true时,num == true是错误的,因为num甚至不是布尔值;-)< / p>

或者换句话说:将when中的“主题”与每个条件进行比较(感谢Bwvolleyball的评论)。


但是我不是很了解(但这也可能是我对语法的误解)...看一下语法,似乎以下情况是可能的:

when {
  is Number -> TODO()
}

但正如人们所料想的那样:并非如此,但最后一句话只是一个旁注。

答案 1 :(得分:1)

//First case
//Prints TRUE if the num value is numeric and true.Anything else prints FALSE
 val num: Any = 2
    when {
        num is Number && true -> println("TRUE")
        else -> println("FALSE")
    }
//Second case
//Prints true if the value is numeric OR true.Anything else prints FALSE
val num: Any = 2
when(num){
         is Number , true -> println("TRUE")
        else -> println("FALSE")
    }
    

答案 2 :(得分:0)

如果您想为 when 语句评估多个条件,您还可以创建一个新变量并在为其赋值时检查所有情况。如果您正在开发一个非常大的应用程序并且必须注意内存,这并不总是最好的情况,但它会使您的代码更具可读性和简洁性

例如:

//num is evaluated for whether it is greater than, less than, or equal to 0 and 
the corresponding String value is assigned to isNumberPositiveNegativeOrZero

var isNumberPositiveNegativeOrZero: String = when {
    num > 0 -> “number is positive”
    num < 0 -> “number is negative”
    else -> “number is zero”
}

当然,这可以扩展到您想要检查的多种情况。 (这是我第一次在这里回答问题,所以请原谅任何意外)

答案 3 :(得分:0)

<块引用>

在使用 when(subject) { ... } 表达式时是否可以提供多个布尔条件?

是的,您可以使用 ,(逗号)分隔多个 when conditions

例如,以下 when 具有完全相同的行为。 Runnable playground demo here

fun withoutComma(arg: Any?): String {
  return when(arg) {
    is String -> "FOO!"  // returned when arg is an instance of String
    true -> "bar!"       // returned when arg == true
    is Long -> "FOO!"    // returned when arg is an instance of Long
    false -> "bar!"      // returned when arg == false
    null -> "FOO!"       // returned when arg == null
    is Int -> "bar!"     // returned when arg is an instance of Int
    else -> "else!"
  }
}

fun withComma(arg: Any?): String {
  return when(arg) {
    is String, is Long, null -> "FOO!"  // returned when arg is an instance of String, or when arg is an instance of Long, or when arg == null
    true, false, is Int -> "bar!"       // returned when arg == true, or when arg == false, or when arg is an instance of Int
    else -> "else!"
  }
}

fun main() {
    listOf("s", true, 999L, false, null, 123, emptyList<Any>()).forEach {
        println("$it -> withoutComma: ${withoutComma(it)}")
        println("$it -> withComma: ${withComma(it)}")
    }
}

// Prints:
// s -> withoutComma: FOO!
// s -> withComma: FOO!
// true -> withoutComma: bar!
// true -> withComma: bar!
// 999 -> withoutComma: FOO!
// 999 -> withComma: FOO!
// false -> withoutComma: bar!
// false -> withComma: bar!
// null -> withoutComma: FOO!
// null -> withComma: FOO!
// 123 -> withoutComma: bar!
// 123 -> withComma: bar!
// [] -> withoutComma: else!
// [] -> withComma: else!