Skip to content

Commit d6a58e3

Browse files
committed
---
yaml --- r: 30711 b: refs/heads/incoming c: 690525e h: refs/heads/master i: 30709: 1109af9 30707: 9cfe9df 30703: 537d31e v: v3
1 parent 7125faa commit d6a58e3

File tree

2 files changed

+96
-66
lines changed

2 files changed

+96
-66
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: d324a424d8f84b1eb049b12cf34182bda91b0024
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
9-
refs/heads/incoming: 2d3396bef191e06568ecbb7c7dd55667db1d8809
9+
refs/heads/incoming: 690525ed814d3a60560188d7d76e2727d6f22347
1010
refs/heads/dist-snap: 2f32a1581f522e524009138b33b1c7049ced668d
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/incoming/doc/tutorial.md

Lines changed: 95 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -918,9 +918,9 @@ garbage-collected heap to manage all of the objects. This approach is
918918
straightforward both in concept and in implementation, but has
919919
significant costs. Languages that take this approach tend to
920920
aggressively pursue ways to ameliorate allocation costs (think the
921-
Java Virtual Machine). Rust supports this strategy with _shared
922-
boxes_: memory allocated on the heap that may be referred to (shared)
923-
by multiple variables.
921+
Java Virtual Machine). Rust supports this strategy with _managed
922+
boxes_: memory allocated on the heap whose lifetime is managed
923+
by the garbage collector.
924924

925925
By comparison, languages like C++ offer very precise control over
926926
where objects are allocated. In particular, it is common to put them
@@ -950,16 +950,16 @@ inefficient for large data structures. Because of this, Rust also
950950
employs a global _exchange heap_. Objects allocated in the exchange
951951
heap have _ownership semantics_, meaning that there is only a single
952952
variable that refers to them. For this reason, they are referred to as
953-
_unique boxes_. All tasks may allocate objects on the exchange heap,
953+
_owned boxes_. All tasks may allocate objects on the exchange heap,
954954
then transfer ownership of those objects to other tasks, avoiding
955955
expensive copies.
956956

957957
## What to be aware of
958958

959959
Rust has three "realms" in which objects can be allocated: the stack,
960960
the local heap, and the exchange heap. These realms have corresponding
961-
pointer types: the borrowed pointer (`&T`), the shared box (`@T`),
962-
and the unique box (`~T`). These three sigils will appear
961+
pointer types: the borrowed pointer (`&T`), the managed box (`@T`),
962+
and the owned box (`~T`). These three sigils will appear
963963
repeatedly as we explore the language. Learning the appropriate role
964964
of each is key to using Rust effectively.
965965

@@ -978,17 +978,22 @@ records with mutable fields, it can be useful to have a single copy on
978978
the heap, and refer to that through a pointer.
979979

980980
Rust supports several types of pointers. The safe pointer types are
981-
`@T` for shared boxes allocated on the local heap, `~T`, for
981+
`@T` for managed boxes allocated on the local heap, `~T`, for
982982
uniquely-owned boxes allocated on the exchange heap, and `&T`, for
983983
borrowed pointers, which may point to any memory, and whose lifetimes
984984
are governed by the call stack.
985985

986986
All pointer types can be dereferenced with the `*` unary operator.
987987

988-
## Shared boxes
988+
> ***Note***: You may also hear managed boxes referred to as 'shared
989+
> boxes' or 'shared pointers', and owned boxes as 'unique boxes/pointers'.
990+
> Borrowed pointers are sometimes called 'region pointers'. The preferred
991+
> terminology is as presented here.
989992
990-
Shared boxes are pointers to heap-allocated, garbage collected memory.
991-
Creating a shared box is done by simply applying the unary `@`
993+
## Managed boxes
994+
995+
Managed boxes are pointers to heap-allocated, garbage collected memory.
996+
Creating a managed box is done by simply applying the unary `@`
992997
operator to an expression. The result of the expression will be boxed,
993998
resulting in a box of the right type. Copying a shared box, as happens
994999
during assignment, only copies a pointer, never the contents of the
@@ -1000,22 +1005,24 @@ let y = x; // Copy the pointer, increase refcount
10001005
// When x and y go out of scope, refcount goes to 0, box is freed
10011006
~~~~
10021007

1003-
Shared boxes never cross task boundaries.
1008+
Managed boxes never cross task boundaries.
10041009

1005-
> ***Note:*** shared boxes are currently reclaimed through reference
1010+
> ***Note:*** managed boxes are currently reclaimed through reference
10061011
> counting and cycle collection, but we will switch to a tracing
1007-
> garbage collector.
1012+
> garbage collector eventually.
10081013
1009-
## Unique boxes
1014+
## Owned boxes
10101015

1011-
In contrast to shared boxes, unique boxes have a single owner and thus
1012-
two unique boxes may not refer to the same memory. All unique boxes
1013-
across all tasks are allocated on a single _exchange heap_, where
1014-
their uniquely owned nature allows them to be passed between tasks.
1016+
In contrast to maneged boxes, owned boxes have a single owning memory
1017+
slot and thus two owned boxes may not refer to the same memory. All
1018+
owned boxes across all tasks are allocated on a single _exchange
1019+
heap_, where their uniquely owned nature allows them to be passed
1020+
between tasks.
10151021

1016-
Because unique boxes are uniquely owned, copying them involves allocating
1017-
a new unique box and duplicating the contents. Copying unique boxes
1018-
is expensive so the compiler will complain if you do.
1022+
Because owned boxes are uniquely owned, copying them involves allocating
1023+
a new owned box and duplicating the contents. Copying owned boxes
1024+
is expensive so the compiler will complain if you do so without writing
1025+
the word `copy`.
10191026

10201027
~~~~
10211028
let x = ~10;
@@ -1029,23 +1036,23 @@ let x = ~10;
10291036
let y = copy x;
10301037
~~~~
10311038

1032-
This is where the 'move' (`<-`) operator comes in. It is similar to
1033-
`=`, but it de-initializes its source. Thus, the unique box can move
1039+
This is where the 'move' operator comes in. It is similar to
1040+
`copy`, but it de-initializes its source. Thus, the owned box can move
10341041
from `x` to `y`, without violating the constraint that it only has a
10351042
single owner (if you used assignment instead of the move operator, the
10361043
box would, in principle, be copied).
10371044

10381045
~~~~
10391046
let x = ~10;
1040-
let y <- x;
1047+
let y = move x;
10411048
~~~~
10421049

10431050
> ***Note:*** this discussion of copying vs moving does not account
10441051
> for the "last use" rules that automatically promote copy operations
10451052
> to moves. This is an evolving area of the language that will
10461053
> continue to change.
10471054
1048-
Unique boxes, when they do not contain any shared boxes, can be sent
1055+
Owned boxes, when they do not contain any managed boxes, can be sent
10491056
to other tasks. The sending task will give up ownership of the box,
10501057
and won't be able to access it afterwards. The receiving task will
10511058
become the sole owner of the box.
@@ -1054,7 +1061,7 @@ become the sole owner of the box.
10541061

10551062
Rust borrowed pointers are a general purpose reference/pointer type,
10561063
similar to the C++ reference type, but guaranteed to point to valid
1057-
memory. In contrast to unique pointers, where the holder of a unique
1064+
memory. In contrast to owned pointers, where the holder of a unique
10581065
pointer is the owner of the pointed-to memory, borrowed pointers never
10591066
imply ownership. Pointers may be borrowed from any type, in which case
10601067
the pointer is guaranteed not to outlive the value it points to.
@@ -1095,11 +1102,12 @@ fn increase_contents(pt: @mut int) {
10951102
}
10961103
~~~~
10971104

1098-
# Vectors
1105+
# Vectors and strings
10991106

11001107
Vectors are a contiguous section of memory containing zero or more
11011108
values of the same type. Like other types in Rust, vectors can be
1102-
stored on the stack, the local heap, or the exchange heap.
1109+
stored on the stack, the local heap, or the exchange heap. Borrowed
1110+
pointers to vectors are also called 'slices'.
11031111

11041112
~~~
11051113
enum Crayon {
@@ -1108,24 +1116,19 @@ enum Crayon {
11081116
BananaMania, Beaver, Bittersweet
11091117
}
11101118
1111-
// A stack vector of crayons
1119+
// A fixed-size stack vector
1120+
let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot];
1121+
1122+
// A borrowed pointer to stack allocated vector
11121123
let stack_crayons: &[Crayon] = &[Almond, AntiqueBrass, Apricot];
1113-
// A local heap (shared) vector of crayons
1124+
1125+
// A local heap (managed) vector of crayons
11141126
let local_crayons: @[Crayon] = @[Aquamarine, Asparagus, AtomicTangerine];
1115-
// An exchange heap (unique) vector of crayons
1127+
1128+
// An exchange heap (owned) vector of crayons
11161129
let exchange_crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
11171130
~~~
11181131

1119-
> ***Note:*** Until recently Rust only had unique vectors, using the
1120-
> unadorned `[]` syntax for literals. This syntax is still supported
1121-
> but is deprecated. In the future it will probably represent some
1122-
> "reasonable default" vector type.
1123-
>
1124-
> Unique vectors are the currently-recommended vector type for general
1125-
> use as they are the most tested and well-supported by existing
1126-
> libraries. There will be a gradual shift toward using more
1127-
> stack and local vectors in the coming releases.
1128-
11291132
Vector literals are enclosed in square brackets and dereferencing is
11301133
also done with square brackets (zero-based):
11311134

@@ -1135,24 +1138,24 @@ also done with square brackets (zero-based):
11351138
# BananaMania, Beaver, Bittersweet };
11361139
# fn draw_scene(c: Crayon) { }
11371140
1138-
let crayons = ~[BananaMania, Beaver, Bittersweet];
1141+
let crayons = [BananaMania, Beaver, Bittersweet];
11391142
match crayons[0] {
11401143
Bittersweet => draw_scene(crayons[0]),
11411144
_ => ()
11421145
}
11431146
~~~~
11441147

11451148
By default, vectors are immutable—you can not replace their elements.
1146-
The type written as `~[mut T]` is a vector with mutable
1147-
elements. Mutable vector literals are written `~[mut]` (empty) or `~[mut
1149+
The type written as `[mut T]` is a vector with mutable
1150+
elements. Mutable vector literals are written `[mut]` (empty) or `[mut
11481151
1, 2, 3]` (with elements).
11491152

11501153
~~~~
11511154
# enum Crayon { Almond, AntiqueBrass, Apricot,
11521155
# Aquamarine, Asparagus, AtomicTangerine,
11531156
# BananaMania, Beaver, Bittersweet };
11541157
1155-
let crayons = ~[mut BananaMania, Beaver, Bittersweet];
1158+
let crayons = [mut BananaMania, Beaver, Bittersweet];
11561159
crayons[0] = AtomicTangerine;
11571160
~~~~
11581161

@@ -1183,7 +1186,30 @@ let your_crayons = ~[BananaMania, Beaver, Bittersweet];
11831186
my_crayons += your_crayons;
11841187
~~~~
11851188

1186-
## Vector and string methods
1189+
> ***Note:*** The above examples of vector addition use owned
1190+
> vectors. Some operations on slices and stack vectors are
1191+
> not well supported yet, owned vectors are often the most
1192+
> usable.
1193+
1194+
Strings are simply vectors of `[u8]`, though they have a distinct
1195+
type. They support most of the same allocation aptions as
1196+
vectors, though the string literal without a storage sigil, e.g.
1197+
`"foo"` is treated differently than a comparable vector (`[foo]`).
1198+
Where
1199+
1200+
~~~
1201+
// A plain string is a slice to read-only (static) memory
1202+
let stack_crayons: &str = "Almond, AntiqueBrass, Apricot";
1203+
1204+
// The same thing, but without
1205+
let stack_crayons: &str = &"Almond, AntiqueBrass, Apricot";
1206+
1207+
// A local heap (managed) string
1208+
let local_crayons: @str = @"Aquamarine, Asparagus, AtomicTangerine";
1209+
1210+
// An exchange heap (owned) string
1211+
let exchange_crayons: ~str = ~"BananaMania, Beaver, Bittersweet";
1212+
~~~
11871213

11881214
Both vectors and strings support a number of useful
11891215
[methods](#implementation). While we haven't covered methods yet,
@@ -1202,7 +1228,7 @@ brief look at a few common ones.
12021228
# fn store_crayon_in_nasal_cavity(i: uint, c: Crayon) { }
12031229
# fn crayon_to_str(c: Crayon) -> ~str { ~"" }
12041230
1205-
let crayons = ~[Almond, AntiqueBrass, Apricot];
1231+
let crayons = &[Almond, AntiqueBrass, Apricot];
12061232
12071233
// Check the length of the vector
12081234
assert crayons.len() == 3;
@@ -1282,15 +1308,15 @@ position and cannot be stored in structures nor returned from
12821308
functions. Despite the limitations stack closures are used
12831309
pervasively in Rust code.
12841310

1285-
## Shared closures
1311+
## Managed closures
12861312

12871313
When you need to store a closure in a data structure, a stack closure
12881314
will not do, since the compiler will refuse to let you store it. For
12891315
this purpose, Rust provides a type of closure that has an arbitrary
12901316
lifetime, written `fn@` (boxed closure, analogous to the `@` pointer
12911317
type described earlier).
12921318

1293-
A boxed closure does not directly access its environment, but merely
1319+
A managed closure does not directly access its environment, but merely
12941320
copies out the values that it closes over into a private data
12951321
structure. This means that it can not assign to these variables, and
12961322
will not 'see' updates to them.
@@ -1315,7 +1341,7 @@ This example uses the long closure syntax, `fn@(s: ~str) ...`,
13151341
making the fact that we are declaring a box closure explicit. In
13161342
practice boxed closures are usually defined with the short closure
13171343
syntax introduced earlier, in which case the compiler will infer
1318-
the type of closure. Thus our boxed closure example could also
1344+
the type of closure. Thus our managed closure example could also
13191345
be written:
13201346

13211347
~~~~
@@ -1324,13 +1350,13 @@ fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
13241350
}
13251351
~~~~
13261352

1327-
## Unique closures
1353+
## Owned closures
13281354

1329-
Unique closures, written `fn~` in analogy to the `~` pointer type,
1355+
Owned closures, written `fn~` in analogy to the `~` pointer type,
13301356
hold on to things that can safely be sent between
1331-
processes. They copy the values they close over, much like boxed
1357+
processes. They copy the values they close over, much like managed
13321358
closures, but they also 'own' them—meaning no other code can access
1333-
them. Unique closures are used in concurrent code, particularly
1359+
them. Owned closures are used in concurrent code, particularly
13341360
for spawning [tasks](#tasks).
13351361

13361362
## Closure compatibility
@@ -1346,12 +1372,16 @@ that callers have the flexibility to pass whatever they want.
13461372
fn call_twice(f: fn()) { f(); f(); }
13471373
call_twice(|| { ~"I am an inferred stack closure"; } );
13481374
call_twice(fn&() { ~"I am also a stack closure"; } );
1349-
call_twice(fn@() { ~"I am a boxed closure"; });
1350-
call_twice(fn~() { ~"I am a unique closure"; });
1375+
call_twice(fn@() { ~"I am a managed closure"; });
1376+
call_twice(fn~() { ~"I am a owned closure"; });
13511377
fn bare_function() { ~"I am a plain function"; }
13521378
call_twice(bare_function);
13531379
~~~~
13541380

1381+
> ***Note:*** Both the syntax and the semantics will be changing
1382+
> in small ways. At the moment they can be unsound in multiple
1383+
> scenarios, particularly with non-copyable types.
1384+
13551385
## Do syntax
13561386

13571387
Closures in Rust are frequently used in combination with higher-order
@@ -1360,7 +1390,7 @@ functions to simulate control structures like `if` and
13601390
integers, passing in a pointer to each integer in the vector:
13611391

13621392
~~~~
1363-
fn each(v: ~[int], op: fn(v: &int)) {
1393+
fn each(v: &[int], op: fn(v: &int)) {
13641394
let mut n = 0;
13651395
while n < v.len() {
13661396
op(&v[n]);
@@ -1378,9 +1408,9 @@ closure to provide the final operator argument, we can write it in a
13781408
way that has a pleasant, block-like structure.
13791409

13801410
~~~~
1381-
# fn each(v: ~[int], op: fn(v: &int)) { }
1411+
# fn each(v: &[int], op: fn(v: &int)) { }
13821412
# fn do_some_work(i: int) { }
1383-
each(~[1, 2, 3], |n| {
1413+
each(&[1, 2, 3], |n| {
13841414
debug!("%i", *n);
13851415
do_some_work(*n);
13861416
});
@@ -1390,9 +1420,9 @@ This is such a useful pattern that Rust has a special form of function
13901420
call that can be written more like a built-in control structure:
13911421

13921422
~~~~
1393-
# fn each(v: ~[int], op: fn(v: &int)) { }
1423+
# fn each(v: &[int], op: fn(v: &int)) { }
13941424
# fn do_some_work(i: int) { }
1395-
do each(~[1, 2, 3]) |n| {
1425+
do each(&[1, 2, 3]) |n| {
13961426
debug!("%i", *n);
13971427
do_some_work(*n);
13981428
}
@@ -1438,7 +1468,7 @@ Consider again our `each` function, this time improved to
14381468
break early when the iteratee returns `false`:
14391469

14401470
~~~~
1441-
fn each(v: ~[int], op: fn(v: &int) -> bool) {
1471+
fn each(v: &[int], op: fn(v: &int) -> bool) {
14421472
let mut n = 0;
14431473
while n < v.len() {
14441474
if !op(&v[n]) {
@@ -1454,7 +1484,7 @@ And using this function to iterate over a vector:
14541484
~~~~
14551485
# use each = vec::each;
14561486
# use println = io::println;
1457-
each(~[2, 4, 8, 5, 16], |n| {
1487+
each(&[2, 4, 8, 5, 16], |n| {
14581488
if *n % 2 != 0 {
14591489
println(~"found odd number!");
14601490
false
@@ -1471,7 +1501,7 @@ to the next iteration, write `again`.
14711501
~~~~
14721502
# use each = vec::each;
14731503
# use println = io::println;
1474-
for each(~[2, 4, 8, 5, 16]) |n| {
1504+
for each(&[2, 4, 8, 5, 16]) |n| {
14751505
if *n % 2 != 0 {
14761506
println(~"found odd number!");
14771507
break;
@@ -1486,7 +1516,7 @@ function, not just the loop body.
14861516

14871517
~~~~
14881518
# use each = vec::each;
1489-
fn contains(v: ~[int], elt: int) -> bool {
1519+
fn contains(v: &[int], elt: int) -> bool {
14901520
for each(v) |x| {
14911521
if (*x == elt) { return true; }
14921522
}

0 commit comments

Comments
 (0)