What is meaning of "where" keyword?
case let x where x.hasSuffix("pepper")
The simple explanation is that you cannot match a case, that is of type String
, with .hasSuffix()
because it returns a Bool
. So, they give you this where
pattern matching keyword to use. It works like this:
let x
copies the String value you are passing into the switch to the constant x.where
is a boolean evaluation that will only let the case complete the match if it is given a true bool, just like anif
block.hasSuffix()
returns the bool required bywhere
.
If your string variable passed into the switch is var foo
. You can literally do this instead:
case foo where foo.hasSuffix("pepper")
You can pass a true bool to where like this and it would work, uselessly:
case foo where true
This is a larger view of the code:
switch vegetable {
... omissis ...
case let x where x.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(x)?"
default:
let vegetableComment = "Everything tastes good in soup."
}
What it does is match the value of vegetable
assigning it to x
and testing if it has suffix "pepper"
. If the match succeeds it executes the case block let vegetableComment = "Is it a spicy \(x)?"
otherwise it continues with the next test (which in this case is a default:
).
Note that the let
is necessary. It means that you are binding a new variable x
.
Also note that it's not the same as
case let x:
if (x.hasSuffix("pepper")
...
as this always succeeds and enters the case block, while using the where
clause means that if the condition is not satisfied the match fails and the next case
(or default
) shall be tried.
The where
in that context is used as pattern matching. From the example:
case let x where x.hasSuffix("pepper"):
When the suffix of x
matches "pepper"
it will set the constant vegetableComment
:
let vegetableComment = "Is it a spicy \(x)?"
You can see as well that x
can´t be "celery", "cucumber" or "watercress", otherwise it would give you a different outcome:
case "celery":
let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
Because those cases are before case let x where x.hasSuffix("pepper"):
. You can try changing the order of them and pass the value "celery" to see a different outcome.
Edit:
From my understanding it creates a constant x
if x
's suffix is "pepper". The goal of creating this constant, is for you to use it after that:
let vegetableComment = "Is it a spicy \(x)?"
Edit 2:
After a bit more research, that's called value binding and it's described as:
switch case can bind the value or values it matches to temporary constants or variables, for use in the body of the case. This is known as value binding, because the values are “bound” to temporary constants or variables within the case’s body.
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/gb/jEUH0.l