@@ -434,11 +434,57 @@ Over half of the switch cases in a large corpus of packages contain either a
434434single return statement or an assignment followed by a break so there is some
435435evidence this will be useful.
436436
437- ** TODO: Something like an if statement that matches a single pattern and binds
438- its variables in the then branch.**
437+ ### If-case statement
439438
440- ** TODO: Something like a Swift guard-let that matches a single pattern and binds
441- in the rest of the block or exits if the pattern does not match.**
439+ Often you want to conditionally match and destructure some data, but you only
440+ want to test a value against a single pattern. You can use a ` switch ` statement
441+ for that, but it's pretty verbose:
442+
443+ ``` dart
444+ switch (json) {
445+ case [int x, int y]:
446+ return Point(x, y);
447+ }
448+ ```
449+
450+ We can make simple uses like this a little cleaner by introducing an if-like
451+ form similar to [ if-case in Swift] [ ] :
452+
453+ [ if-case in swift ] : https://useyourloaf.com/blog/swift-if-case-let/
454+
455+ ``` dart
456+ if (case [int x, int y] = json) return Point(x, y);
457+ ```
458+
459+ It may have an else branch as well:
460+
461+ ``` dart
462+ if (case [int x, int y] = json) {
463+ print('Was coordinate array $x,$y');
464+ } else {
465+ throw FormatException('Invalid JSON.');
466+ }
467+ ```
468+
469+ The grammar is:
470+
471+ ```
472+ ifCaseStatement ::= 'if' '(' 'case' matcher '=' expression ')'
473+ statement ('else' statement)?
474+ ```
475+
476+ The ` expression ` is evaluated and matched against ` matcher ` . If the pattern
477+ matches, then the then branch is executed with any variables the pattern
478+ defines in scope. Otherwise, the else branch is executed if there is one.
479+
480+ Unlike ` switch ` , this form doesn't allow a guard clause. Guards are important in
481+ switch cases because, unlike nesting an if statement * inside* the switch case, a
482+ failed guard will continue to try later cases in the switch. That is less
483+ important here since the only other case is the else branch.
484+
485+ ** TODO: Consider allowing guard clauses here. That probably necessitates
486+ changing guard clauses to use a keyword other than ` if ` since ` if ` nested inside
487+ an ` if ` condition looks pretty strange.**
442488
443489### Irrefutable patterns ("binders")
444490
@@ -865,8 +911,9 @@ arity of the type of `typeName`.
865911
866912A pattern always appears in the context of some value expression that it is
867913being matched against. In a switch statement or expression, the value expression
868- is the value being switched on. In a variable declaration, the value is the
869- initializer:
914+ is the value being switched on. In an if-case statement, the value is the result
915+ of the expression to the right of the ` = ` . In a variable declaration, the value
916+ is the initializer:
870917
871918``` dart
872919var (a, b) = (1, 2);
@@ -1221,6 +1268,7 @@ that contains the pattern:
12211268* **Switch statement case**: The guard clause and the statements of the
12221269 subsequent non-empty case body.
12231270* **Switch expression case**: The guard clause and the case expression.
1271+ * **If-case statement**: The then statement.
12241272
12251273Multiple switch case patterns may share the same variable scope if their case
12261274bodies are empty:
@@ -1371,6 +1419,15 @@ behavior.
13711419 expression after it and yield that as the result of the entire switch
13721420 expression.
13731421
1422+ #### If-case statement
1423+
1424+ 1 . Evaluate the ` expression ` producing ` v ` .
1425+
1426+ 2 . Match the ` matcher ` pattern against ` v ` .
1427+
1428+ 3 . If the match succeeds, evaluate the then ` statement ` . Otherwise, if there
1429+ is an ` else ` clause, evaluate the else ` statement ` .
1430+
13741431### Matching (refuting and destructuring)
13751432
13761433At runtime, a pattern is matched against a value. This determines whether or not
@@ -1523,6 +1580,8 @@ main() {
15231580- Add a shorthand for destructuring a named record field to a variable with
15241581 the same name.
15251582
1583+ - Add if-case statement.
1584+
15261585### 1.1
15271586
15281587- Copy editing and clean up.
0 commit comments