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
Related
Using Alamofire we're trying to determine if an error is a certain kind of error (response code 499) as represented by a "nested" AFError enum:
if response.result.isFailure {
if let aferror = error as? AFError {
//THIS LINE FAILS
if (aferror == AFError.responseValidationFailed(reason: AFError.ResponseValidationFailureReason.unacceptableStatusCode(code: 499))) {
....
}
}
}
But this results in the compiler error:
Binary operator '==' cannot be applied to two 'AFError' operands
How can you do this?
Well, you could trying extending AFEError to conform to Equatable in order to use ==, but you are probably better off using switch and pattern matching:
switch aferror {
case .responseValidationFailed(let reason) :
switch reason {
case AFError.ResponseValidationFailureReason.unacceptableStatusCode(let code):
if code == 499 { print("do something here") }
default:
print("You should handle all inner cases")
{
default:
print("Handle other AFError cases")
}
This is the best syntax to ensure (and get the compiler to help you ensure) that all possible error cases and reasons are handled. If you only want to address a single case, like in your example, you can use the newer if case syntax, like this:
if case .responseValidationFailed(let reason) = aferror, case AFError.ResponseValidationFailureReason.unacceptableStatusCode(let code) = reason, code == 499 {
print("Your code for this case here")
}
As I point out here, you cannot, by default, apply the equality (==) operator between cases of an enum that as an associated value (on any of its cases); but there are many other ways to find out whether this is the desired case (and, if there is an associated value, to learn what the associated value may be).
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.
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.
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: ()