Skip to content

Commit 2d80047

Browse files
committed
Discuss if-case and for-case in Control Flow
Using a pattern with these constructs isn't specific to enums, even though that's a place where it's nearly indispensable. It makes more sense to introduce the 'case' version alongside each of the plain versions -- folks are also more likely to look in that chapter than in the Enumerations chapter if they're trying to look this up.
1 parent db2ade0 commit 2d80047

File tree

2 files changed

+63
-26
lines changed

2 files changed

+63
-26
lines changed

TSPL.docc/LanguageGuide/ControlFlow.md

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,33 +1442,76 @@ can always access a value for `distance`.
14421442

14431443
## Patterns
14441444

1445-
XXX OUTLINE:
1446-
1447-
- Each switch case takes a *pattern*
1448-
that describes what values that case handles
1449-
- You can also use patterns with if and for
1450-
- The for-case syntax is useful when you want to iterate
1451-
over only certain elements in a collection
1452-
- Because patterns can bind values,
1453-
they're also useful for working with enumerations that have associated values
1454-
XREF <doc:Enumerations#Associated-Values>
1445+
In the previous examples, each switch case includes a pattern
1446+
that indicates what values match that case.
1447+
You can also use a pattern as the condition for an `if` statement.
1448+
Here's what that looks like:
14551449

14561450
```swift
14571451
let somePoint = (12, 100)
14581452
if case (let x, 100) = somePoint {
1459-
print("Found a point with x of \(x)")
1453+
print("Found a point on the y=100 line, at \(x)")
14601454
}
1455+
// Prints "Found a point on the y=100 line, at 12"
1456+
```
1457+
1458+
In this code,
1459+
the condition for the `if` statement starts with `case`,
1460+
indicating that the condition is a pattern instead of a Boolean value.
1461+
If the pattern matches,
1462+
the condition for the `if` is considered to be true,
1463+
and the code in the body of the `if` statement runs.
1464+
The patterns you can write after `if case`
1465+
are the same as the patterns you can write in a switch case.
14611466

1467+
You can also use a pattern in a `for`-`in` loop,
1468+
to give names to parts of the value using a value binding:
1469+
1470+
```swift
14621471
let points = [(10, 0), (30, 100), (-20, 0)]
1463-
for case (let x, let y) in points {
1464-
guard y == 0 else { continue }
1465-
print("Found a point on the x-axis at \(x)")
1472+
1473+
for case let (x, y) in points {
1474+
if y == 0 {
1475+
print("Found a point on the x-axis at \(x)")
1476+
}
14661477
}
1467-
for case (let x, let y) in points where y == 0 {
1478+
// Prints "Found a point on the x-axis at 10"
1479+
// Prints "Found a point on the x-axis at -20"
1480+
```
1481+
1482+
The `for`-`in` loop above iterates over an array of tuples,
1483+
binding the first and second elements of the tuples
1484+
to the `x` and `y` constants.
1485+
The statements inside the loop can use those constants,
1486+
like the `if` statement that checks whether the point lies on the x-axis.
1487+
1488+
A `for`-`case`-`in` loop can also include a `where` clause,
1489+
to check for an additional condition.
1490+
The statements inside the loop run
1491+
only when `where` clause matches the current element.
1492+
For example,
1493+
the `for`-`case`-`in` loop below is the same as the `for`-`in` loop above.
1494+
1495+
```swift
1496+
for case let (x, y) in points where y == 0 {
14681497
print("Found a point on the x-axis at \(x)")
14691498
}
1499+
// Prints "Found a point on the x-axis at 10"
1500+
// Prints "Found a point on the x-axis at -20"
14701501
```
14711502

1503+
In this code,
1504+
the condition is integrated into the `for`-`case`-`in` loop as part of the pattern.
1505+
The statements in the `for`-`case`-`in` loop run only for points on the x-axis.
1506+
This code produces the same result as the `for`-`in` loop above,
1507+
but is a more compact way to iterate
1508+
over only certain elements in a collection.
1509+
1510+
Because patterns can bind values,
1511+
`if`-`case` statements and `for`-`case`-`in` loops
1512+
are useful for working with enumerations that have associated values,
1513+
as described in <doc:Enumerations#Associated-Values>.
1514+
14721515
## Control Transfer Statements
14731516

14741517
*Control transfer statements* change the order in which your code is executed,
@@ -2012,6 +2055,8 @@ without wrapping it in an `else` block,
20122055
and it lets you keep the code that handles a violated requirement
20132056
next to the requirement.
20142057

2058+
<!-- XXX show guard-case syntax for completeness? -->
2059+
20152060
## Deferred Actions
20162061

20172062
Unlike control-flow constructs like `if` and `while`,

TSPL.docc/LanguageGuide/Enumerations.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ case let .qrCode(productCode):
482482
When you're matching just one case of an enumeration ---
483483
for example,
484484
to extract its associated value ---
485-
there's a shorter syntax you can use
485+
you can use an `if`-`case` statement
486486
instead of writing a full switch statement.
487487
Here's what it looks like:
488488

@@ -492,21 +492,13 @@ if case .qrCode(let productCode) = productBarcode {
492492
}
493493
```
494494

495-
In this code,
496-
the condition for the `if` statement starts with `case`,
497-
indicating that the condition is a pattern instead of a Boolean value.
498-
If the pattern matches,
499-
the condition for the `if` is considered to be true,
500-
and the code in the body of the `if` statement runs.
501-
The patterns you can write after `if case`
502-
are the same as the patterns you can write in a switch case.
503495
Just like in the switch statement earlier,
504496
the `productBarcode` variable is matched against
505497
the pattern `.qrCode(let productCode)` here.
506498
And like in the switch case,
507499
writing `let` extracts the associated value as a constant.
508-
509-
<!-- XXX mention guards, and maybe for loops -->
500+
For more information about `if`-`case` statements,
501+
see <doc:ControlFlow#Patterns>.
510502

511503
## Raw Values
512504

0 commit comments

Comments
 (0)