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 |