I'd suggest to not put them together.
case
in Swift means "try to match the following pattern against a value": the pattern (that is, what's on the right of case
) part is consistent in all case
statements, while the value part depends on the context.
When switch
ing, the value is the one you're switching on:
switch value {
case patternTheWillBeMatchedAgainstValue:
When if
fing, guard
ing or while
ing, the value is the one on the right of the =
operator that follows the pattern:
if case patternTheWillBeMatchedAgainstValue = value {
I think, as many do, that this could be better. It's rather strange to see a =
there, because that's not an assignment. The other problem, here, is that the value
is spelled after the case
statement, which means that, to get proper autocompletion and everything, you should write first
if case = value {
then put the cursor after case
and enjoy autocompletion.
Maybe a better way would be something like:
if value match case patternTheWillBeMatchedAgainstValue {
Anyway, when for
ing, the value is the Element
of the Sequence
that's being cycled:
for case patternTheWillBeMatchedAgainstValue in sequenceOfValues {
because for
doesn't allow for multiple patterns to matched, it's more limited than, say, while
, but it's generally good enough.
But the fact that for
allows for a pattern to be matched against the values of the sequence allows for code like this:
for case 3 in [1, 2, 3, 1, 2, 3] {
print("a 3 was found")
}
/// prints "a 3 was found" twice
Notice that, thanks to how case
works, you can add assignments in the middle of a sequence of patterns, because let x =
is also a pattern (sorry for the convoluted code):
enum MyError: Error {
case this
case that
}
let stringResults: [Result<String, MyError>] = [
.success("11"),
.success("a2"),
.failure(.this),
.success("2"),
.failure(.that),
.success("bb")
]
if let firstResult = stringResults.first,
case .success(let value) = firstResult,
case let count = value.count, /// interesting line
let intValue = Int("\(count)") {
print("A value was found with count \(intValue)")
}
If you just wrote let count = value.count
it wouldn't compile, because we need to tell Swift that's we're matching against a pattern there (thus, the need for the case
keyword).