| OLD | NEW |
| 1 --- | 1 --- |
| 2 layout: book | 2 layout: book |
| 3 title: "A Tour of the Dart Language" | 3 title: "A Tour of the Dart Language" |
| 4 subsite: "Dart Up and Running" | 4 subsite: "Dart Up and Running" |
| 5 description: "Read Chapter 2, A Tour of the Dart Language of Dart (from Dart: Up
and Running, published by O'Reilly)." | 5 description: "Read Chapter 2, A Tour of the Dart Language of Dart (from Dart: Up
and Running, published by O'Reilly)." |
| 6 prev-chapter: ch01.html | 6 prev-chapter: ch01.html |
| 7 prev-chapter-title: "Quick Start" | 7 prev-chapter-title: "Quick Start" |
| 8 next-chapter: ch03.html | 8 next-chapter: ch03.html |
| 9 next-chapter-title: "Library Tour" | 9 next-chapter-title: "Library Tour" |
| 10 --- | 10 --- |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 {% endprettify %} | 730 {% endprettify %} |
| 731 | 731 |
| 732 The <code>=> <em>expr</em>;</code> syntax is a shorthand for | 732 The <code>=> <em>expr</em>;</code> syntax is a shorthand for |
| 733 <code>{ return <em>expr</em>;}</code>. In the `printNumber()` function, the expr
ession is the | 733 <code>{ return <em>expr</em>;}</code>. In the `printNumber()` function, the expr
ession is the |
| 734 call to the top-level `print()` function. | 734 call to the top-level `print()` function. |
| 735 | 735 |
| 736 <aside class="alert alert-info" markdown="1"> | 736 <aside class="alert alert-info" markdown="1"> |
| 737 **Note:** | 737 **Note:** |
| 738 Only an *expression*—not a *statement*—can appear between the arrow | 738 Only an *expression*—not a *statement*—can appear between the arrow |
| 739 (=\>) and the semicolon (;). For example, you can’t put an [if | 739 (=\>) and the semicolon (;). For example, you can’t put an [if |
| 740 statement](#if-and-else) there, but you can use a [conditional (`?:`) | 740 statement](#if-and-else) there, but you can use a [conditional |
| 741 expression](#other-operators). | 741 expression](#conditional-expressions). |
| 742 </aside> | 742 </aside> |
| 743 | 743 |
| 744 Here’s an example of calling a function: | 744 Here’s an example of calling a function: |
| 745 | 745 |
| 746 <!-- ch02/function_calling.dart --> | 746 <!-- ch02/function_calling.dart --> |
| 747 {% prettify dart %} | 747 {% prettify dart %} |
| 748 printNumber(123); | 748 printNumber(123); |
| 749 {% endprettify %} | 749 {% endprettify %} |
| 750 | 750 |
| 751 A function can have two types of parameters: required and optional. The | 751 A function can have two types of parameters: required and optional. The |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 | 1045 |
| 1046 ## Operators {#operators} | 1046 ## Operators {#operators} |
| 1047 | 1047 |
| 1048 Dart defines the operators shown in the following table. | 1048 Dart defines the operators shown in the following table. |
| 1049 You can override many of these operators, as described in | 1049 You can override many of these operators, as described in |
| 1050 [Overridable operators](#overridable-operators). | 1050 [Overridable operators](#overridable-operators). |
| 1051 | 1051 |
| 1052 |--------------------------+------------------------------------------------| | 1052 |--------------------------+------------------------------------------------| |
| 1053 |Description | Operator | | 1053 |Description | Operator | |
| 1054 |--------------------------|------------------------------------------------| | 1054 |--------------------------|------------------------------------------------| |
| 1055 | unary postfix | <code><em>expr</em>++</code> <code><em>expr</em>
--</code> `()` `[]` `.` | | 1055 | unary postfix | <code><em>expr</em>++</code> <code><em>expr</em>
--</code> `()` `[]` `.` `?.` | |
| 1056 | unary prefix | <code>-<em>expr</em></code> <code>!<em>expr</em>
</code> <code>~<em>expr</em></code> <code>++<em>expr</em></code> <code>
--<em>expr</em></code> | | 1056 | unary prefix | <code>-<em>expr</em></code> <code>!<em>expr</em>
</code> <code>~<em>expr</em></code> <code>++<em>expr</em></code> <code>
--<em>expr</em></code> | |
| 1057 | multiplicative | `*` `/` `%` `~/` | | 1057 | multiplicative | `*` `/` `%` `~/` | |
| 1058 | additive | `+` `-` | | 1058 | additive | `+` `-` | |
| 1059 | shift | `<<` `>>` | | 1059 | shift | `<<` `>>` | |
| 1060 | bitwise AND | `&` | | 1060 | bitwise AND | `&` | |
| 1061 | bitwise XOR | `^` | | 1061 | bitwise XOR | `^` | |
| 1062 | bitwise OR | `|` | | 1062 | bitwise OR | `|` | |
| 1063 | relational and type test | `>=` `>` `<=` `<` `as`
`is` `is!` | | 1063 | relational and type test | `>=` `>` `<=` `<` `as`
`is` `is!` | |
| 1064 | equality | `==` `!=` | | 1064 | equality | `==` `!=` | |
| 1065 | logical AND | `&&` | | 1065 | logical AND | `&&` | |
| 1066 | logical OR | `||` | | 1066 | logical OR | `||` | |
| 1067 | conditional | <code><em>expr1</em> ? <em>expr2</em> : <em>expr3</
em></code> | | 1067 | if null | `??` | |
| 1068 | conditional | <code><em>expr1</em> ? <em>expr2</em> : <em>expr3</
em></code> | |
| 1068 | cascade | `..` | | 1069 | cascade | `..` | |
| 1069 | assignment | `=` `*=` `/=` `~/=` `%=` `+=` `-=
` `<<=` `>>=` `&=` `^=` `|=` | | 1070 | assignment | `=` `*=` `/=` `~/=` `%=` `+=` `-=
` `<<=` `>>=` `&=` `^=` `|=` `??=` | |
| 1070 {:.table .table-striped} | 1071 {:.table .table-striped} |
| 1071 | 1072 |
| 1072 When you use operators, you create expressions. Here are some examples | 1073 When you use operators, you create expressions. Here are some examples |
| 1073 of operator expressions: | 1074 of operator expressions: |
| 1074 | 1075 |
| 1075 <!-- TODO: write test for this --> | 1076 <!-- TODO: write test for this --> |
| 1076 {% prettify dart %} | 1077 {% prettify dart %} |
| 1077 a++ | 1078 a++ |
| 1078 a + b | 1079 a + b |
| 1079 a = b | 1080 a = b |
| 1080 a == b | 1081 a == b |
| 1081 a ? b: c | 1082 a ? b: c |
| 1082 a is T | 1083 a is T |
| 1083 {% endprettify %} | 1084 {% endprettify %} |
| 1084 | 1085 |
| 1085 In the preceding operator table, | 1086 In the [operator table](#operators), |
| 1086 each operator has higher precedence than the operators in the rows | 1087 each operator has higher precedence than the operators in the rows |
| 1087 that follow it. For example, the multiplicative operator `%` has higher | 1088 that follow it. For example, the multiplicative operator `%` has higher |
| 1088 precedence than (and thus executes before) the equality operator `==`, | 1089 precedence than (and thus executes before) the equality operator `==`, |
| 1089 which has higher precedence than the logical AND operator `&&`. That | 1090 which has higher precedence than the logical AND operator `&&`. That |
| 1090 precedence means that the following two lines of code execute the same | 1091 precedence means that the following two lines of code execute the same |
| 1091 way: | 1092 way: |
| 1092 | 1093 |
| 1093 <!-- ch02/precedence.dart --> | 1094 <!-- ch02/precedence.dart --> |
| 1094 {% prettify dart %} | 1095 {% prettify dart %} |
| 1095 // 1: Parens improve readability. | 1096 // 1: Parens improve readability. |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 **Note:** | 1262 **Note:** |
| 1262 The code isn’t equivalent. If `emp` is null or not a Person, the | 1263 The code isn’t equivalent. If `emp` is null or not a Person, the |
| 1263 first example (with `is`) does nothing; the second (with `as`) throws | 1264 first example (with `is`) does nothing; the second (with `as`) throws |
| 1264 an exception. | 1265 an exception. |
| 1265 </aside> | 1266 </aside> |
| 1266 | 1267 |
| 1267 | 1268 |
| 1268 ### Assignment operators {#assignment-operators} | 1269 ### Assignment operators {#assignment-operators} |
| 1269 {:.no_toc} | 1270 {:.no_toc} |
| 1270 | 1271 |
| 1271 As you’ve already seen, you assign values using the `=` operator. You | 1272 As you’ve already seen, you can assign values using the `=` operator. |
| 1272 can also use compound assignment operators such as `+=`, which combine | 1273 To assign only if the assigned-to variable is null, |
| 1274 use the `??=` operator. |
| 1275 |
| 1276 {% prettify dart %} |
| 1277 a = value; // Assign value to a |
| 1278 b ??= value; // If b is null, assign value to b; |
| 1279 // otherwise, b stays the same |
| 1280 {% endprettify %} |
| 1281 |
| 1282 {% include null-aware-1-12.html %} |
| 1283 |
| 1284 {% comment %} |
| 1285 <!-- embed a dartpad when we can hide code --> |
| 1286 https://gist.github.com/9de887c4daf76d39e524 |
| 1287 https://dartpad.dartlang.org/9de887c4daf76d39e524 |
| 1288 {% endcomment %} |
| 1289 |
| 1290 Compound assignment operators such as `+=` combine |
| 1273 an operation with an assignment. | 1291 an operation with an assignment. |
| 1274 | 1292 |
| 1275 | `=` | `–=` | `/=` | `%=` | `>>=` | `^=` | 1293 | `=` | `–=` | `/=` | `%=` | `>>=` | `^=` |
| 1276 | `+=` | `*=` | `~/=` | `<<=` | `&=` | `|=` | 1294 | `+=` | `*=` | `~/=` | `<<=` | `&=` | `|=` |
| 1277 {:.table} | 1295 {:.table} |
| 1278 | 1296 |
| 1279 Here’s how compound assignment operators work: | 1297 Here’s how compound assignment operators work: |
| 1280 | 1298 |
| 1281 |-----------+----------------------+-----------------------| | 1299 |-----------+----------------------+-----------------------| |
| 1282 | | Compound assignment | Equivalent expression | | 1300 | | Compound assignment | Equivalent expression | |
| 1283 |-----------+----------------------+-----------------------| | 1301 |-----------+----------------------+-----------------------| |
| 1284 |**For an operator <em>op</em>:** | <code>a <em>op</em>= b</code> | <code>a = a
<em>op</em> b</code> | 1302 |**For an operator <em>op</em>:** | <code>a <em>op</em>= b</code> | <code>a = a
<em>op</em> b</code> |
| 1285 |**Example:** |`a += b` | `a = a + b` | 1303 |**Example:** |`a += b` | `a = a + b` |
| 1286 {:.table} | 1304 {:.table} |
| 1287 | 1305 |
| 1288 The following example uses both assignment and compound assignment | 1306 The following example uses assignment and compound assignment |
| 1289 operators: | 1307 operators: |
| 1290 | 1308 |
| 1291 <!-- ch02/op_assign.dart --> | 1309 <!-- ch02/op_assign.dart --> |
| 1292 {% prettify dart %} | 1310 {% prettify dart %} |
| 1293 var a = 2; // Assign using = | 1311 var a = 2; // Assign using = |
| 1294 a *= 3; // Assign and multiply: a = a * 3 | 1312 a *= 3; // Assign and multiply: a = a * 3 |
| 1295 assert(a == 6); | 1313 assert(a == 6); |
| 1296 {% endprettify %} | 1314 {% endprettify %} |
| 1297 | 1315 |
| 1298 | 1316 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1346 | 1364 |
| 1347 assert((value & bitmask) == 0x02); // AND | 1365 assert((value & bitmask) == 0x02); // AND |
| 1348 assert((value & ~bitmask) == 0x20); // AND NOT | 1366 assert((value & ~bitmask) == 0x20); // AND NOT |
| 1349 assert((value | bitmask) == 0x2f); // OR | 1367 assert((value | bitmask) == 0x2f); // OR |
| 1350 assert((value ^ bitmask) == 0x2d); // XOR | 1368 assert((value ^ bitmask) == 0x2d); // XOR |
| 1351 assert((value << 4) == 0x220); // Shift left | 1369 assert((value << 4) == 0x220); // Shift left |
| 1352 assert((value >> 4) == 0x02); // Shift right | 1370 assert((value >> 4) == 0x02); // Shift right |
| 1353 {% endprettify %} | 1371 {% endprettify %} |
| 1354 | 1372 |
| 1355 | 1373 |
| 1374 ### Conditional expressions {#conditional-expressions} |
| 1375 {:.no_toc} |
| 1376 |
| 1377 Dart has two operators that let you concisely evaluate expressions |
| 1378 that might otherwise require [if-else](#if-and-else) statements: |
| 1379 |
| 1380 <code><em>condition</em> ? <em>expr1</em> : <em>expr2</em> |
| 1381 : If _condition_ is true, evaluates _expr1_ (and returns its value); |
| 1382 otherwise, evaluates and returns the value of _expr2_. |
| 1383 |
| 1384 <code><em>expr1</em> ?? <em>expr2</em></code> |
| 1385 : If _expr1_ is non-null, returns its value; |
| 1386 otherwise, evaluates and returns the value of _expr2_. |
| 1387 |
| 1388 {% include null-aware-1-12.html %} |
| 1389 |
| 1390 When you need to assign a value |
| 1391 based on a boolean expression, |
| 1392 consider using `?:`. |
| 1393 |
| 1394 <!-- ch03/mirrors.dart --> |
| 1395 {% prettify dart %} |
| 1396 var finalStatus = m.isFinal ? 'final' : 'not final'; |
| 1397 {% endprettify %} |
| 1398 |
| 1399 If the boolean expression tests for null, |
| 1400 consider using `??`. |
| 1401 |
| 1402 {% prettify dart %} |
| 1403 String toString() => msg ?? super.toString(); |
| 1404 {% endprettify %} |
| 1405 |
| 1406 The previous example could have been written at least two other ways, |
| 1407 but not as succinctly: |
| 1408 |
| 1409 {% comment %} |
| 1410 https://dartpad.dartlang.org/f2c8d82ce5d0dd533fe2 |
| 1411 https://gist.github.com/f2c8d82ce5d0dd533fe2 |
| 1412 {% endcomment %} |
| 1413 |
| 1414 {% prettify dart %} |
| 1415 // Slightly longer version uses ?: operator. |
| 1416 String toString() => msg == null ? super.toString() : msg; |
| 1417 |
| 1418 // Very long version uses if-else statement. |
| 1419 String toString() { |
| 1420 if (msg == null) { |
| 1421 return super.toString(); |
| 1422 } else { |
| 1423 return msg; |
| 1424 } |
| 1425 } |
| 1426 {% endprettify %} |
| 1427 |
| 1356 ### Other operators {#other-operators} | 1428 ### Other operators {#other-operators} |
| 1357 {:.no_toc} | 1429 {:.no_toc} |
| 1358 | 1430 |
| 1359 A few operators remain, most of which you’ve already seen in other | 1431 You've seen most of the remaining operators in other examples: |
| 1360 examples. | |
| 1361 | 1432 |
| 1362 |----------+-------------------------------------------| | 1433 |----------+-------------------------------------------| |
| 1363 | Operator | Name | Meaning
| | 1434 | Operator | Name | Meaning | |
| 1364 |-----------+-------------------------------------------| | 1435 |-----------+------------------------------------------| |
| 1365 | `()` | Function application | Represents a function call | 1436 | `()` | Function application | Represents a function call |
| 1366 | `[]` | List access | Refers to the value at the specified index i
n the list | 1437 | `[]` | List access | Refers to the value at the specified index i
n the list |
| 1367 | <code><em>expr1</em> ? <em>expr2</em> : <em>expr3</em> | Conditional | If _exp
r1_ is true, executes _expr2_; otherwise, executes _expr3_ | |
| 1368 | `.` | Member access | Refers to a property of an expression; examp
le: `foo.bar` selects property `bar` from expression `foo` | 1438 | `.` | Member access | Refers to a property of an expression; examp
le: `foo.bar` selects property `bar` from expression `foo` |
| 1439 | `?.` | Conditional member access | Like `.`, but the leftmost operand can
be null; example: `foo?.bar` selects property `bar` from expression `foo` unless
`foo` is null (in which case the value of `foo?.bar` is null) |
| 1369 | `..` | Cascade | Allows you to perform multiple operations on
the members of a single object; described in [Classes](#classes) | 1440 | `..` | Cascade | Allows you to perform multiple operations on
the members of a single object; described in [Classes](#classes) |
| 1370 {:.table .table-striped} | 1441 {:.table .table-striped} |
| 1371 | 1442 |
| 1443 For more information about the `.`, `?.`, and `..` operators, see |
| 1444 [Classes](#classes). |
| 1445 |
| 1372 | 1446 |
| 1373 ## Control flow statements {#control-flow-statements} | 1447 ## Control flow statements {#control-flow-statements} |
| 1374 | 1448 |
| 1375 You can control the flow of your Dart code using any of the following: | 1449 You can control the flow of your Dart code using any of the following: |
| 1376 | 1450 |
| 1377 - `if` and `else` | 1451 - `if` and `else` |
| 1378 | 1452 |
| 1379 - `for` loops | 1453 - `for` loops |
| 1380 | 1454 |
| 1381 - `while` and `do`-`while` loops | 1455 - `while` and `do`-`while` loops |
| 1382 | 1456 |
| 1383 - `break` and `continue` | 1457 - `break` and `continue` |
| 1384 | 1458 |
| 1385 - `switch` and `case` | 1459 - `switch` and `case` |
| 1386 | 1460 |
| 1387 - `assert` | 1461 - `assert` |
| 1388 | 1462 |
| 1389 You can also affect the control flow using `try-catch` and `throw`, as | 1463 You can also affect the control flow using `try-catch` and `throw`, as |
| 1390 explained in [Exceptions](#exceptions). | 1464 explained in [Exceptions](#exceptions). |
| 1391 | 1465 |
| 1392 | 1466 |
| 1393 ### If and else {#if-and-else} | 1467 ### If and else {#if-and-else} |
| 1394 {:.no_toc} | 1468 {:.no_toc} |
| 1395 | 1469 |
| 1396 Dart supports `if` statements with optional `else` statements, as the | 1470 Dart supports `if` statements with optional `else` statements, as the |
| 1397 next sample shows. Also see conditional expressions (?:), which are | 1471 next sample shows. Also see [conditional expressions](#conditional-expressions). |
| 1398 covered in [Other operators](#other-operators). | |
| 1399 | 1472 |
| 1400 <!-- ch02/flow_if_else.dart --> | 1473 <!-- ch02/flow_if_else.dart --> |
| 1401 {% prettify dart %} | 1474 {% prettify dart %} |
| 1402 if (isRaining()) { | 1475 if (isRaining()) { |
| 1403 you.bringRainCoat(); | 1476 you.bringRainCoat(); |
| 1404 } else if (isSnowing()) { | 1477 } else if (isSnowing()) { |
| 1405 you.wearJacket(); | 1478 you.wearJacket(); |
| 1406 } else { | 1479 } else { |
| 1407 car.putTopDown(); | 1480 car.putTopDown(); |
| 1408 } | 1481 } |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1797 | 1870 |
| 1798 // Create a Point using Point.fromJson(). | 1871 // Create a Point using Point.fromJson(). |
| 1799 var p2 = new Point.fromJson(jsonData); | 1872 var p2 = new Point.fromJson(jsonData); |
| 1800 {% endprettify %} | 1873 {% endprettify %} |
| 1801 | 1874 |
| 1802 Objects have *members* consisting of functions and data (*methods* and | 1875 Objects have *members* consisting of functions and data (*methods* and |
| 1803 *instance variables*, respectively). When you call a method, you *invoke* | 1876 *instance variables*, respectively). When you call a method, you *invoke* |
| 1804 it on an object: the method has access to that object’s functions and | 1877 it on an object: the method has access to that object’s functions and |
| 1805 data. | 1878 data. |
| 1806 | 1879 |
| 1807 Use a dot (.) to refer to an instance variable or method: | 1880 Use a dot (`.`) to refer to an instance variable or method: |
| 1808 | 1881 |
| 1809 <!-- ch02/object_classes.dart --> | 1882 <!-- ch02/object_classes.dart --> |
| 1810 {% prettify dart %} | 1883 {% prettify dart %} |
| 1811 var p = new Point(2, 2); | 1884 var p = new Point(2, 2); |
| 1812 | 1885 |
| 1813 // Set the value of the instance variable y. | 1886 // Set the value of the instance variable y. |
| 1814 p.y = 3; | 1887 p.y = 3; |
| 1815 | 1888 |
| 1816 // Get the value of y. | 1889 // Get the value of y. |
| 1817 assert(p.y == 3); | 1890 assert(p.y == 3); |
| 1818 | 1891 |
| 1819 // Invoke distanceTo() on p. | 1892 // Invoke distanceTo() on p. |
| 1820 num distance = p.distanceTo(new Point(4, 4)); | 1893 num distance = p.distanceTo(new Point(4, 4)); |
| 1821 {% endprettify %} | 1894 {% endprettify %} |
| 1822 | 1895 |
| 1896 Use `?.` instead of `.` to avoid an exception |
| 1897 when the leftmost operand is null: |
| 1898 |
| 1899 {% comment %} |
| 1900 https://dartpad.dartlang.org/0cb25997742ed5382e4a |
| 1901 https://gist.github.com/0cb25997742ed5382e4a |
| 1902 {% endcomment %} |
| 1903 |
| 1904 {% prettify dart %} |
| 1905 // If p is non-null, set its y value to 4. |
| 1906 p?.y = 4; |
| 1907 {% endprettify %} |
| 1908 |
| 1909 {% include null-aware-1-12.html %} |
| 1910 |
| 1823 Use the cascade operator (..) when you want to perform a series of | 1911 Use the cascade operator (..) when you want to perform a series of |
| 1824 operations on the members of a single object: | 1912 operations on the members of a single object: |
| 1825 | 1913 |
| 1826 <!-- ch02/cascade_operator/web/web_app.dart --> | 1914 <!-- ch02/cascade_operator/web/web_app.dart --> |
| 1827 {% prettify dart %} | 1915 {% prettify dart %} |
| 1828 querySelector('#button') // Get an object. | 1916 querySelector('#button') // Get an object. |
| 1829 ..text = 'Confirm' // Use its members. | 1917 ..text = 'Confirm' // Use its members. |
| 1830 ..classes.add('important') | 1918 ..classes.add('important') |
| 1831 ..onClick.listen((e) => window.alert('Confirmed!')); | 1919 ..onClick.listen((e) => window.alert('Confirmed!')); |
| 1832 {% endprettify %} | 1920 {% endprettify %} |
| 1833 | 1921 |
| 1834 Some classes provide constant constructors. To create a compile-time | 1922 Some classes provide constant constructors. To create a compile-time |
| 1835 constant using a constant constructor, use `const` instead of `new`: | 1923 constant using a constant constructor, use `const` instead of `new`: |
| 1836 | 1924 |
| 1837 <!-- ch02/object_classes.dart --> | 1925 <!-- ch02/object_classes.dart --> |
| 1838 {% prettify dart %} | 1926 {% prettify dart %} |
| 1839 var p = const ImmutablePoint(2, 2); | 1927 var p = const ImmutablePoint(2, 2); |
| 1840 {% endprettify %} | 1928 {% endprettify %} |
| 1841 | 1929 |
| (...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3537 This chapter summarized the commonly used features in the Dart language. | 3625 This chapter summarized the commonly used features in the Dart language. |
| 3538 More features are being implemented, but we expect that they won’t break | 3626 More features are being implemented, but we expect that they won’t break |
| 3539 existing code. For more information, see the [Dart Language | 3627 existing code. For more information, see the [Dart Language |
| 3540 Specification](/docs/spec/) and | 3628 Specification](/docs/spec/) and |
| 3541 [articles](/articles/) such as [Idiomatic | 3629 [articles](/articles/) such as [Idiomatic |
| 3542 Dart.](/articles/idiomatic-dart/) | 3630 Dart.](/articles/idiomatic-dart/) |
| 3543 | 3631 |
| 3544 | 3632 |
| 3545 <hr> | 3633 <hr> |
| 3546 {% include book-nav.html %} | 3634 {% include book-nav.html %} |
| OLD | NEW |