@@ -874,13 +874,7 @@ switch (obj) {
874
874
An extractor combines a type test and record destructuring. It matches if the
875
875
object has the named type. If so, it then uses the following record pattern to
876
876
destructure fields on the value as that type. This pattern is particularly
877
- useful for writing code in an algebraic datatype style.
878
-
879
- ```
880
- extractMatcher ::= typeName typeArgumentsOrBinders? "(" recordFieldMatchers ")"
881
- ```
882
-
883
- For example:
877
+ useful for writing code in an algebraic datatype style. For example:
884
878
885
879
``` dart
886
880
class Rect {
@@ -898,12 +892,43 @@ display(Object obj) {
898
892
}
899
893
```
900
894
895
+ You can also use an extractor to both match an enum value and destructure
896
+ fields from it:
897
+
898
+ ``` dart
899
+ enum Severity {
900
+ error(1, "Error"),
901
+ warning(2, "Warning");
902
+
903
+ Severity(this.level, this.prefix);
904
+
905
+ final int level;
906
+ final String prefix;
907
+ }
908
+
909
+ log(Severity severity, String message) {
910
+ switch (severity) {
911
+ case Severity.error(_, prefix):
912
+ print('!! $prefix !! $message'.toUppercase());
913
+ case Severity.warning(_, prefix):
914
+ print('$prefix: $message');
915
+ }
916
+ }
917
+ ```
918
+
919
+ The grammar is:
920
+
921
+ ```
922
+ extractMatcher ::= extractName typeArgumentsOrBinders? "(" recordFieldMatchers ")"
923
+ extractName ::= typeIdentifier | qualifiedName
924
+ ```
925
+
901
926
It requires the type to be a named type. If you want to use an extractor with a
902
927
function type, you can use a typedef.
903
928
904
- It is a compile-time error if ` typeName ` does not refer to a type. It is a
905
- compile-time error if a type argument list is present and does not match the
906
- arity of the type of ` typeName ` .
929
+ It is a compile-time error if ` extractName ` does not refer to a type or enum
930
+ value. It is a compile-time error if a type argument list is present and does
931
+ not match the arity of the type of ` extractName ` .
907
932
908
933
** TODO: Some kind of terse null-check pattern that matches a non-null value?**
909
934
@@ -1540,12 +1565,14 @@ To match a pattern `p` against a value `v`:
1540
1565
1 . If ` v ` is not a subtype of the extractor pattern's type, then the
1541
1566
match fails.
1542
1567
1543
- 2 . Otherwise, match ` v ` against the subpatterns of ` p ` as if it were a
1568
+ 2 . If the extractor pattern refers to an enum value and ` v ` is not that
1569
+ value, then the match fails.
1570
+
1571
+ 3 . Otherwise, match ` v ` against the subpatterns of ` p ` as if it were a
1544
1572
record pattern.
1545
1573
1546
- ** TODO: Define order of evaluation and specify how much freedom compilers have
1547
- to reorder or skip tests. What happens if the various desugared operations have
1548
- side effects?**
1574
+ ** TODO: Update to specify that the result of operations can be cached across
1575
+ cases. See: https://github.com/dart-lang/language/issues/2107 **
1549
1576
1550
1577
### Late and static variables in pattern declaration
1551
1578
@@ -1582,6 +1609,8 @@ main() {
1582
1609
1583
1610
- Add if-case statement.
1584
1611
1612
+ - Allow extractor patterns to match enum values.
1613
+
1585
1614
### 1.1
1586
1615
1587
1616
- Copy editing and clean up.
0 commit comments