How to check all cases in a switch statement in swift using where keyword?

2k views Asked by At

when I execute this code just the print("it is greater than zero") gets executed but I have two cases where it's true, I've tried to use the fallthrough keyword but it executes the next case block even if it's false, no matter what,

which in turn raises another question, when should I use fallthrough keyword? if I want to forcefully execute the next block why don't just insert the code into the same block where fallthrough sits?

Is there any way that the example below could print all cases that evaluate to true and still rule out all cases that evaluate to false?

let number = 1

switch number {
case _ where number > 0:
    print("it is greater than zero")
case _ where number < 2:
    print("it is less than two")
case _ where number < 0:
    print("it is less than zero")
default:
    print("default")
}

Thank you in advance for your answers!

2

There are 2 answers

0
Rob Napier On

The switch statement isn't for this purpose, and doesn't work this way. It's intent to to find a single true case. If you want to check multiple cases, that's just an if statement:

let number = 1

if number > 0 {
    print("it is greater than zero")
}
if number < 2 {
    print("it is less than two")
}
if number < 0 {
    print("it is less than zero")
}

There is no equivalent switch for this. They're different control statements.

As you've discovered, fallthrough exists to allow two cases to run the same block. That's what it's for; it doesn't check the other cases. As a rule, if you're using case _ extensively, you're probably not using switch correctly in Swift and should be using if.

1
matt On

You are correct that fallthrough means "do the next case without checking its truth value".

So if you want to execute the first and second cases just in the situation where both are true, you must perform the second check as part of the first case. The minimal change from your code would thus be:

let number = 1
switch number {
case _ where number > 0:
    print("it is greater than zero")
    if number < 2 { fallthrough } // <--
case _ where number < 2:
    print("it is less than two")
case _ where number < 0:
    print("it is less than zero")
default:
    print("default")
}

However, that's not how I would write this particular example. And in any case you still face the problem of what should happen when the number is, say, -1; that is less than 2 but also less than 0, so you face the same issue again. It is not at all obvious from your question what the actual goal is here! If those are really the three things you want to detect, you'd be better off using two separate tests, as they are not cleanly related to one another. For example:

let number = 1
switch number {
case ..<0:
    print("it is less than zero")
case 0...:
    print("it is zero or greater")
default: break
}
switch number {
case ..<2:
    print("it is less than two")
default: break
}