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 case
s 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
Swift Casting Generic to Optional with a Nil Value Causes Fatalerror
Apple Mach-O Linker Error (Static, Not Ld)
Comma Automatically Being Added to Textfield in Swift
Macos App Sandboxing - Read Access to Referenced Files from Parsed Xml
Cast While Looping Over Dictionary in Swift
Parse Weird Bug in Swift That Causes Acl Write Permissions to Change to an Objectid
How to Create Rounded Image with Border and Shadow as Mkannotationview in Swift
Filter, Closure, Functional Syntax Version of for Loop with Multiple Conditions
Reactive Cocoa/Reactive Swift - Swift 3.0 Missing Methods
Swift: Object Instance by Name
How to Get Unsaferawpointer on The Swift Object
How to Provide Default Implementation of an Objective-C Protocol in a Swift Protocol Extension
Underlying Type for Tuple in Swift
Uibutton Borders Function Only Gives Back White Borders
Why Is Swift Giving Me Inaccurate Floating Point Arithmetic Results