@@ -1252,17 +1252,32 @@ fn contains(v: ~[int], elt: int) -> bool {
1252
1252
1253
1253
# Datatypes
1254
1254
1255
- Rust datatypes are, by default, immutable. The core datatypes of Rust
1256
- are structural records and 'enums' (tagged unions, algebraic data
1257
- types) .
1255
+ The core datatypes of Rust are structural records, enums (tagged
1256
+ unions, algebraic data types), and classes. They are immutable
1257
+ by default .
1258
1258
1259
1259
~~~~
1260
1260
type point = {x: float, y: float};
1261
+
1261
1262
enum shape {
1262
1263
circle(point, float),
1263
1264
rectangle(point, point)
1264
1265
}
1265
- let my_shape = circle({x: 0.0, y: 0.0}, 10.0);
1266
+
1267
+ class drawing {
1268
+ let mut shapes: [shape];
1269
+
1270
+ new() {
1271
+ self.shapes = [];
1272
+ }
1273
+
1274
+ fn add_shape(new_shape: shape) {
1275
+ self.shapes += [new_shape];
1276
+ }
1277
+ }
1278
+
1279
+ let my_drawing = drawing();
1280
+ my_drawing.add_shape(circle({x: 0.0, y: 0.0}, 10.0));
1266
1281
~~~~
1267
1282
1268
1283
## Records
@@ -1271,12 +1286,10 @@ Rust record types are written `{field1: T1, field2: T2 [, ...]}`,
1271
1286
where `T1`, `T2`, ... denote types. Record literals are written in
1272
1287
the same way, but with expressions instead of types. They are quite
1273
1288
similar to C structs, and even laid out the same way in memory (so you
1274
- can read from a Rust struct in C, and vice-versa).
1275
-
1276
- The dot operator is used to access record fields (`mypoint.x`).
1289
+ can read from a Rust struct in C, and vice-versa). The dot operator is
1290
+ used to access record fields (`mypoint.x`).
1277
1291
1278
- Fields that you want to mutate must be explicitly marked as such. For
1279
- example...
1292
+ Fields that you want to mutate must be explicitly marked `mut`.
1280
1293
1281
1294
~~~~
1282
1295
type stack = {content: ~[int], mut head: uint};
@@ -1286,16 +1299,16 @@ With such a type, you can do `mystack.head += 1u`. If `mut` were
1286
1299
omitted from the type, such an assignment would result in a type
1287
1300
error.
1288
1301
1289
- To 'update' an immutable record, you use functional record update
1290
- syntax, by ending a record literal with the keyword `with`:
1302
+ To create a new record based on the value of an existing record
1303
+ you construct it using the `with` keyword :
1291
1304
1292
1305
~~~~
1293
1306
let oldpoint = {x: 10f, y: 20f};
1294
1307
let newpoint = {x: 0f with oldpoint};
1295
1308
assert newpoint == {x: 0f, y: 20f};
1296
1309
~~~~
1297
1310
1298
- This will create a new struct , copying all the fields from `oldpoint`
1311
+ This will create a new record , copying all the fields from `oldpoint`
1299
1312
into it, except for the ones that are explicitly set in the literal.
1300
1313
1301
1314
Rust record types are *structural*. This means that `{x: float, y:
@@ -1329,8 +1342,8 @@ the fields of a record, a record pattern may end with `, _` (as in
1329
1342
1330
1343
## Enums
1331
1344
1332
- Enums are datatypes that have several different representations. For
1333
- example, the type shown earlier:
1345
+ Enums are datatypes that have several alternate representations. For
1346
+ example, consider the type shown earlier:
1334
1347
1335
1348
~~~~
1336
1349
# type point = {x: float, y: float};
@@ -1352,7 +1365,7 @@ which can be used to construct values of the type (taking arguments of
1352
1365
the specified types). So `circle({x: 0f, y: 0f}, 10f)` is the way to
1353
1366
create a new circle.
1354
1367
1355
- Enum variants do not have to have parameters. This, for example, is
1368
+ Enum variants need not have type parameters. This, for example, is
1356
1369
equivalent to a C enum:
1357
1370
1358
1371
~~~~
@@ -1448,8 +1461,8 @@ fn point_from_direction(dir: direction) -> point {
1448
1461
1449
1462
Tuples in Rust behave exactly like records, except that their fields
1450
1463
do not have names (and can thus not be accessed with dot notation).
1451
- Tuples can have any arity except for 0 or 1 (though you may see nil,
1452
- `()`, as the empty tuple if you like).
1464
+ Tuples can have any arity except for 0 or 1 (though you may consider
1465
+ nil, `()`, as the empty tuple if you like).
1453
1466
1454
1467
~~~~
1455
1468
let mytup: (int, int, float) = (10, 20, 30.0);
@@ -1472,11 +1485,15 @@ allocating memory and going through a pointer. But for big records, or
1472
1485
records with mutable fields, it can be useful to have a single copy on
1473
1486
the heap, and refer to that through a pointer.
1474
1487
1475
- Rust supports several types of pointers. The simplest is the unsafe
1476
- pointer, written `*T`, which is a completely unchecked pointer type
1477
- only used in unsafe code (and thus, in typical Rust code, very
1478
- rarely). The safe pointer types are `@T` for shared, reference-counted
1479
- boxes, and `~T`, for uniquely-owned pointers.
1488
+ Rust supports several types of pointers. The safe pointer types are
1489
+ `@T` for shared boxes allocated on the local heap, `~T`, for
1490
+ uniquely-owned boxes allocated on the exchange heap, and `&T`, for
1491
+ borrowed pointers, which may point to any memory, and whose lifetimes
1492
+ are governed by the call stack.
1493
+
1494
+ Rust also has an unsafe pointer, written `*T`, which is a completely
1495
+ unchecked pointer type only used in unsafe code (and thus, in typical
1496
+ Rust code, very rarely).
1480
1497
1481
1498
All pointer types can be dereferenced with the `*` unary operator.
1482
1499
@@ -1496,20 +1513,32 @@ let y = x; // Copy the pointer, increase refcount
1496
1513
// When x and y go out of scope, refcount goes to 0, box is freed
1497
1514
~~~~
1498
1515
1499
- ***Note:*** We may in the future switch to garbage collection, rather
1516
+ ***Note:*** We will in the future switch to garbage collection, rather
1500
1517
than reference counting, for shared boxes.
1501
1518
1502
1519
Shared boxes never cross task boundaries.
1503
1520
1504
1521
### Unique boxes
1505
1522
1506
- In contrast to shared boxes, unique boxes are not reference counted.
1507
- Instead, it is statically guaranteed that only a single owner of the
1508
- box exists at any time.
1523
+ In contrast to shared boxes, unique boxes have a single owner and thus
1524
+ two unique boxes may not refer to the same memory. All unique boxes
1525
+ across all tasks are allocated on a single _exchange heap_, where
1526
+ their uniquely owned nature allows them to be passed between tasks.
1527
+
1528
+ Because unique boxes are uniquely owned, copying them involves allocating
1529
+ a new unique box and duplicating the contents. Copying unique boxes
1530
+ is expensive so the compiler will complain if you do.
1509
1531
1510
1532
~~~~
1511
1533
let x = ~10;
1512
- let y <- x;
1534
+ let y = x; // error: copying a non-implicitly copyable type
1535
+ ~~~~
1536
+
1537
+ If you really want to copy a unique box you must say so explicitly.
1538
+
1539
+ ~~~~
1540
+ let x = ~10;
1541
+ let y = copy x;
1513
1542
~~~~
1514
1543
1515
1544
This is where the 'move' (`<-`) operator comes in. It is similar to
@@ -1518,6 +1547,11 @@ from `x` to `y`, without violating the constraint that it only has a
1518
1547
single owner (if you used assignment instead of the move operator, the
1519
1548
box would, in principle, be copied).
1520
1549
1550
+ ~~~~
1551
+ let x = ~10;
1552
+ let y <- x;
1553
+ ~~~~
1554
+
1521
1555
Unique boxes, when they do not contain any shared boxes, can be sent
1522
1556
to other tasks. The sending task will give up ownership of the box,
1523
1557
and won't be able to access it afterwards. The receiving task will
0 commit comments