Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the Kotlin "when" expression support compound boolean expression when using a subject?

Tags:

kotlin

Is it possible to provide a compound boolean expression in the when(subject) { ... } block?

The following will not compile

val num: Any = 2
when(num) {
    /* compound boolean expression that uses implicit subject expression
     * and an independent expression */
    is Number && true -> println("TRUE")
    else -> println("FALSE")
}

The following will compile, but results in FALSE. Is this the expected behavior?

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

I have a long list of when conditions and most of them only use the implicit subject but a couple need secondary conditions

like image 584
geg Avatar asked Sep 28 '18 02:09

geg


People also ask

What does when do in Kotlin?

When{} block is essentially an advanced form of the switch-case statement known from Java. In Kotlin, if a matching case is found then only the code in the respective case block is executed and execution continues with the next statement after the when block.

When operator in Kotlin?

when operator matches its argument with all the branches until it matches with anyone, else it executes the else block. It can be used as an expression where the value of the satisfied branch becomes the value of the overall expression.


3 Answers

Is it possible to provide multiple boolean conditions when using a when(subject) { ... } expression?

Yes, you can separate multiple when conditions using a , (comma).

For instance, the following whens have the exact same behavior. 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!
like image 109
acdcjunior Avatar answered Sep 28 '22 22:09

acdcjunior


//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")
    }
    
like image 29
Dimitris Ligkitsakos Avatar answered Sep 28 '22 23:09

Dimitris Ligkitsakos


If you want to have multiple conditions for the when statement to evaluate, you can also create a new variable and check all your cases when assigning it a value. It’s not always the best case if you’re working on a very large app and have to be conscious about memory, but it makes your code much more readable and concise

ex:

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

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

This can, of course, be expanded into however many cases you want to check. (This is my first time answering a question on here so please excuse any accidents)

like image 27
Tanner Millican Avatar answered Sep 29 '22 00:09

Tanner Millican