What is the difference between line A and line B:
let a = 1
switch a {
case 1:
break;//line A
case 2:
print("2")
default:
()//line B
}
My guess is that break is saying leave the switch, whereas () is saying do nothing.
I'm not sure what to search for this, and I'm new to Swift, so links are appreciated
In your example, there is no difference. They are both placeholders. The rule is that a case cannot be completely empty. Both are acting as ways of meeting that requirement.
Related
This question already has answers here:
Switch in Swift - Case label in a switch should have at least one executable statement
(2 answers)
Noop for Swift's Exhaustive Switch Statements
(8 answers)
Closed 7 years ago.
Here is my code:
enum GameScreen
{
case kSceneFlashScreen
case kSceneMainMenu
case kSceneGameScreen
case kSceneStoreScreen
case kSceneGameOver
}
class YSGameManager: NSObject {
func replaceGameScene(inScreen: GameScreen)
{
switch inScreen
{
case GameScreen.kSceneGameScreen: //Error for here
case GameScreen.kSceneMainMenu : //here also error
}
}
}
Eror LOG: 'case' label in a 'switch' should have at least one executable statement
How to use enum in switch case in Swift ?
There's an error because you haven't got anything after : and before the next case. To solve this you can:
1. Add some code to do something.
2. Add fallthrough if you want to move to the next case. This may have been what you were trying to do. However, in Swift, switch statements don't fallthrough by default to the next case, they break.
3. Add break to stop the switch statement.
It’s complaining that you need to actually do something after the matching case. Otherwise there’s not much point matching it, and chances are it’s a typo.
Other possibly than coverage i.e. if you don’t want a default, you want to name every possible enum, even though you don’t want to do anything for some of them. In which case, stick in a break:
switch inScreen {
case kSceneGameScreen:
break
// etc.
}
Note, there’s no implicit fall through in Swift’s switch statements. You need to give one explicitly:
switch inScreen {
case kSceneGameScreen:
// do a game-screen-specific thing
fallthrough // then
case kSceneMainMenu:
// do a thing for both
// kSceneGameScreen and kSceneMainMenu
// etc.
}
But if you just want to match two possibilities, you don’t need to use fall through, you can just combine them with ,:
switch inScreen {
case kSceneGameScreen, kSceneMainMenu:
// do a thing for both
// kSceneGameScreen and kSceneMainMenu
// etc.
}
I know that the keyword "pass" in Python will allow one to leave a line of code empty where it should have contained an executable statement. Is there a similar keyword in Swift?
I am using a switch statement and Swift requires there to be a default case. The code should reach the default statement most of the time and I want nothing to be done in this case.
You can break out of the default case. Swift just wants you to be explicit about that to avoid bugs.
Here's a simple example:
enum Food {
case Banana
case Apple
case ChocolateBar
}
func warnIfUnhealthy(food : Food) {
switch food {
case .ChocolateBar:
println("Don't eat it!")
default:
break
}
}
let candy = Food.ChocolateBar
warnIfUnhealthy(candy)
The proper way to add a catch-all without an action to a switch statement is to add
default: break
at the end.
Given the following enum in C# and a switch/case to return the a border color of a textbox according its state for example.
enum TextboxState {
Default,
Error
}
switch(foo) {
default:
case TextboxState.Default: return Color.Black;
case TextboxState.Error: return Color.Red;
}
So basically I define a real and not just by convention default state aka TextboxState.Default by adding the default: case. I just want to do this to prevent future breaking changes if new values are added to the enum.
According to the Swift book this is not possible:
“If it is not appropriate to provide a switch case for every possible
value, you can define a default catch-all case to cover any values
that are not addressed explicitly. This catch-all case is indicated by
the keyword default, and must always appear last.”
The paragraph is quite clear about that, so I assume my pattern above does not apply to Swift or do I miss something? Is there another way to archive something like the above code?
You can use fallthrough to do that, by moving the shared behavior in the default case, and using fallthrough in all cases for which you want the shared behavior to occur.
For example, if this is your enum (added a 3rd case to show it can handle multiple fall throughs):
enum TextboxState {
case Default
case Error
case SomethingElse
}
you can format the switch statement as follows:
switch(foo) {
case TextboxState.Error:
return UIColor.redColor()
case TextboxState.Default:
fallthrough
case TextboxState.SomethingElse:
fallthrough
default:
return UIColor.blackColor()
}
Each fallthrough moves the execution point to the next case, up to the default case.
Delete the default: line from your switch. Even if you someday add additional cases to your enum, the Swift compiler will complain if you don't add corresponding cases to every switch that uses the enum. And FYI, you don't need to specify the TextboxState. before the case values in the switch, because the compiler knows that foo is a TextboxState. The resulting code would be:
switch(foo) {
case .Default: return Color.Black;
case .Error: return Color.Red;
}
although, for consistency, I'd put the .Error case before the .Default one.
Swift requires exhaustive switch statements, and that each case have executable code.
'case' label in a 'switch' should have at least one executable statement
Has anybody settled on a good way to handle the cases where you don't want to actually do anything? I can put a println() in there, but that feels dirty.
According to the book, you need to use break there:
The scope of each case can’t be empty. As a result, you must include at least one statement following the colon (:) of each case label. Use a single break statement if you don’t intend to execute any code in the body of a matched case.
You can use a break statement:
let vegetable = "red pepper"
var vegetableComment: String = "Nothing"
switch vegetable {
case "cucumber", "watercress":
break // does nothing
case let x where x.hasSuffix("pepper"):
vegetableComment = "Is it a spicy \(x)?"
default:
vegetableComment = "Everything tastes good in soup."
}
Example modified from the docs
Below is one option for null statement, but maybe not a good solution. I cannot find a statement like python pass
{}()
for switch case, break is better choice.
break
Do nothing in exhaustive switch case statements:
Swift:
switch yourVariable {
case .someCase:
break
}
SwiftUI:
switch yourVariable {
case .someCase:
EmptyView() // break does not work with ViewBuilder
}
Using EmptyView() instead of break in SwiftUI views prevents the error:
Closure containing control flow statement cannot be used with function
builder ViewBuilder.
EmptyView() is a SwiftUI standard view (tested with Xcode 12, iOS 14) and does not need to be defined yourself.
In addition to break mentioned in other answers, I have also seen () used as a no-op statement:
switch 0 == 1 {
case true:
break
case false:
()
}
Use () if you find break confusing or want to save 3 characters.
The cleanest solution I've found is to simply include your last statement in the switch case as your default. This avoids the need to add break or other unnecessary statements while still covering all possible cases.
For example:
switch myVar {
case 0:
myOtherVar = "Red"
case 1:
myOtherVar = "Blue"
default:
myOtherVar = "Green"
}
You can check specific case, no need to be exhustive with switch cases
Say you have a enum like this,
enum Selection {
case one
case two
case three
}
var myCase = Selection.one
you can check like this,
if case .one = myCase {
print("one")
}
A clean solution I use for my default case is:
default: ()
I'm not too fond of the if let syntax with optionals and I'm trying to see if I can get pattern matching to work instead. I'm trying the following code in a playground, but not seeing any output on the println statements. What am I doing wrong?
let one:Int? = 1
switch one {
case .Some(let numeral):
println("Caught a \(numeral)")
default:
println("Nothing to catch")
}
A little bit out of context, but: Playground doesn't print the println() statements in the right column.
You can write again the variable that you want to read:
...
case .Some(let numeral):
println("Caught a \(numeral)")
numeral
...
In this case you'll see {Some 2}.
Or you can open the Assistant Editor (View -> Assistant Editor -> Show Assistant Editor) and read the Console output to read the println() evaluated.
EDIT after Xcode 6 beta-5
With Xcode 6 beta-5, you can finally println(), you'll see the text in the right column.
Yes you can do it by use of underscore ( _ ) to match and ignore any value.
A more succinct way to do what you want with your example would be to use if case let, rather than switch.
if case let numeral? = one {
print("Caught a \(numeral)")
}
or
if case .Some(let numeral) = one {
print("Caught a \(numeral)")
}
Requires Swift 2.0