glez
glez

Reputation: 1214

Swift Constant Assignment Example

I'm a long time developer (java, c, c++, etc.) and a Swift newbie with a question. In the switch statement below where the constant "x" is defined the example states "Notice how let can be used in a pattern to assign the value that matched the pattern to a constant.". I'm a bit confused as the statement does not reference the target variable of the switch statement "vegetable" at all. My thought is it should read:

case let x where vegetable.hasSuffix("pepper"):
        -- or just --
case let x where hasSuffix("pepper"):

and not

    case let x where x.hasSuffix("pepper"):

Any feedback will be appreciated.

Swift Tutorial

let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
default:
    print("Everything tastes good in soup.")
}

Upvotes: 4

Views: 423

Answers (2)

glez
glez

Reputation: 1214

After chatting with @Alexander I have a better understanding of the switch construct. Thanks to him for time and explanations.

As detailed in the "value bindings" section of this Control Constructs documentation I learned that switch statements assign temporary variables to the value of the switch target before the cases are evaluated. So that the right side (temporary x) is assigned the switch target value "red pepper" and the cases pattern matched for each switch case, top to bottom. If the case matches then left side x becomes a permanent constant. Net net, temporary x is defined and set = vegetable then the switch pattern match performed.

 case let x where x.hasSuffix("pepper"):

Upvotes: 0

Alexander
Alexander

Reputation: 63157

The where predicate could directly reference vegetable, this this particular situation, and it compiles fine.

switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let x where vegetable.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
default:
    print("Everything tastes good in soup.")
}

But now consider a more complex patternmatching of vegetable, supposing that it were a String? (a.k.a. Optional<String>) and not String:

let vegetable: String? = "red pepper"
switch vegetable {
case "celery"?:
    print("Add some raisins and make ants on a log.")
case "cucumber"?, "watercress"?:
    print("That would make a good tea sandwich.")
case let x? where vegetable.hasSuffix("pepper"):
    //            ^ error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
    print("Is it a spicy \(x)?")
case nil:
    print("You don't even have a vegetable!")
default:
    print("Everything tastes good in soup.")
}

In this case, x is the non-optional value of vegetable in a non-nil case, which allows use to call .hasSuffix("pepper") on it. It's saying "If it is the case that vegetable has a value, call it x, that happens to end with "pepper", then do this: ..."

Upvotes: 3

Related Questions