Swift: Switch Statement Fallthrough Behavior

swift case falling through

Yes. You can do so as follows:

var testVal = "hello"
var result = 0

switch testVal {
case "one", "two":
result = 1
default:
result = 3
}

Alternatively, you can use the fallthrough keyword:

var testVal = "hello"
var result = 0

switch testVal {
case "one":
fallthrough
case "two":
result = 1
default:
result = 3
}

Swift: Switch statement fallthrough behavior

Fallthrough falls through to the next case, not to the next matching case. The concept is inherited from C switch statements, where each case may be thought of as a goto destination label, and the switch statement brings execution to the first matching one.

In C, the switch statement only dictates where execution starts inside the block. For added convenience, you may use the break statement to skip the rest of the switch body, but nothing forces you to; and if you don't, execution continues normally, like the cases weren't there. For instance:

switch (countdown)
{
case 3: puts("3...");
case 2: puts("2...");
case 1: puts("1...");
case 0: puts("0!");
}

With no break anywhere, if countdown is 3, then you get the whole thing (even though countdown is obviously 3, and not 2, 1 or 0).

When execution goes from a case to another instead of exiting the switch scope (for instance, with a break statement), you get "fall through" (which is what the Swift fallthrough keyword does).

This is relevant in C as you are allowed to use arbitrarily complex structures inside switch statements, overlapping cases if you want. Here is a legal C program:

switch (x)
{
case 0:
if (y == 3)
{
case 1:
puts("hello");
}
else
{
puts("world");
}

case 2:
puts("!");
}

This kind of use is however extremely uncommon and often hard to follow (quick! can the else branch be executed if x == 1?). I haven't tested, but I would be very surprised if you could do something similar with Swift.

In general, in C, fall through is considered poor style since it is often hard to tell if the fall through is voluntary or due to a missing break statement. Swift solves this with the fallthrough statement, which makes it explicit that you want execution to continue to the next case inside the switch statement rather than exit the switch scope.

In your case, you cannot use fallthrough to get what you want, because fallthrough is only useful when the execution sequence you need is linear. You need to skip over invalid blocks of code, so you need to use an if-else sequence instead of a switch statement.

What is wrong with this use of the fallthrough keyword in Swift?

From apple's documentation on fallthrough: "A fallthrough statement causes program execution to continue from one case in a switch statement to the next case. Program execution continues to the next case even if the patterns of the case label do not match the value of the switch statement’s control expression."

So Swift fallthrough is consistent with C behavior.

Switch statement fall-through...should it be allowed?

It may depend on what you consider fallthrough. I'm ok with this sort of thing:

switch (value)
{
case 0:
result = ZERO_DIGIT;
break;

case 1:
case 3:
case 5:
case 7:
case 9:
result = ODD_DIGIT;
break;

case 2:
case 4:
case 6:
case 8:
result = EVEN_DIGIT;
break;
}

But if you have a case label followed by code that falls through to another case label, I'd pretty much always consider that evil. Perhaps moving the common code to a function and calling from both places would be a better idea.

And please note that I use the C++ FAQ definition of "evil"

How to make a switch case in Swift to continue to the next case condition?

Taken from the Apple Swift documentation:

If you really need C-style fallthrough behavior, you can opt in to this behavior on a case-by-case basis with the fallthrough keyword. The example below uses fallthrough to create a textual description of a number:

let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
description += " a prime number, and also"
fallthrough // explicitly tells to continue to the default case
default:
description += " an integer."
}
println(description)
// prints "The number 5 is a prime number, and also an integer."

Is it possible to use 'if-case' in place of a switch that has a coma delimited list as a case?

Well, after nearly a month. This is the closest I could get to satisfying the comma delimited list question. This actually satisfies the same requirement but in a different way.

let tuple = (1,0)

if case (0...1, 0...1) = tuple where !(a == 0 && b == 0) { return true }
else { return false }

Have switch statement's default case call a prior case?

A possible solution is to use fallthrough.

Instead of thinking:

In case of "default": do something of target case

Think it in the other way:

In case of target case, do "default".

switch webView {
case customizerWebView:
customizerURLObserver = customizerWebView.observe(\.url, options: .new) { [weak self] webView, change in
let url = "\(String(describing: change.newValue))"
self?.customizerURLDidChange(urlString: url) }
case webView:
fallthrough
case default:
webViewURLObserver = webView.observe(\.url, options: .new) { [weak self] webView, change in
let url = "\(String(describing: change.newValue))"
self?.urlDidChange(urlString: url) }
}

Or as, pointed by @xTwiteDx, you can remove the lines case webView: fallthrough if you don't do a specific code before fallthrough. It's up to you, how you are comfortable with you code, how to explicit or not cases.

Switch statement in Swift

The usual rules for the FizzBuzz game
are to replace every multiple of 3 by "Fizz", every multiple of 5 by "Buzz", and
every multiple of both 3 and 5 by "FizzBuzz".

This can be done with a switch statement on the tuple (i % 3, i % 5).
Note that _ means "any value":

for i in 1 ... 100 {
switch (i % 3, i % 5) {
case (0, 0):
print("FizzBuzz")
case (0, _):
print("Fizz")
case (_, 0):
print("Buzz")
default:
print(i)
}
}


Related Topics



Leave a reply



Submit