@@ -1240,58 +1240,80 @@ The indexing operator (`[]`) also auto-dereferences.
12401240
12411241# Vectors and strings
12421242
1243- A vector is a contiguous section of memory containing zero or more
1244- values of the same type. Like other types in Rust, vectors can be
1245- stored on the stack, the local heap, or the exchange heap. Borrowed
1246- pointers to vectors are also called 'slices'.
1243+ A vector is a contiguous block of memory containing zero or more values of the
1244+ same type. Rust also supports vector reference types, called slices, which are
1245+ a view into a block of memory represented as a pointer and a length.
1246+
1247+ Strings are represented as vectors of `u8`, with the guarantee of containing a
1248+ valid UTF-8 sequence.
1249+
1250+ Fixed-size vectors are an unboxed block of memory, with the element length as
1251+ part of the type. A fixed-size vector owns the elements it contains, so the
1252+ elements are mutable if the vector is mutable. Fixed-size strings do not exist.
12471253
12481254~~~
1249- # enum Crayon {
1250- # Almond, AntiqueBrass, Apricot,
1251- # Aquamarine, Asparagus, AtomicTangerine,
1252- # BananaMania, Beaver, Bittersweet,
1253- # Black, BlizzardBlue, Blue
1254- # }
1255- // A fixed-size stack vector
1256- let stack_crayons: [ Crayon, ..3] = [ Almond, AntiqueBrass, Apricot] ;
1255+ // A fixed-size vector
1256+ let numbers = [ 1, 2, 3] ;
1257+ let more_numbers = numbers;
12571258
1258- // A borrowed pointer to stack-allocated vector
1259- let stack_crayons: &[ Crayon] = &[ Aquamarine, Asparagus, AtomicTangerine] ;
1259+ // The type of a fixed-size vector is written as ` [Type, ..length] `
1260+ let five_zeroes: [ int, ..5] = [ 0, ..5] ;
1261+ ~~~
12601262
1261- // A local heap (managed) vector of crayons
1262- let local_crayons: @[ Crayon] = @[ BananaMania, Beaver, Bittersweet] ;
1263+ A unique vector is dynamically sized, and has a destructor to clean up
1264+ allocated memory on the heap. A unique vector owns the elements it contains, so
1265+ the elements are mutable if the vector is mutable.
12631266
1264- // An exchange heap (owned) vector of crayons
1265- let exchange_crayons: ~ [ Crayon] = ~ [ Black, BlizzardBlue, Blue] ;
12661267~~~
1268+ // A dynamically sized vector (unique vector)
1269+ let mut numbers = ~ [ 1, 2, 3] ;
1270+ numbers.push(4);
1271+ numbers.push(5);
12671272
1268- The `+` operator means concatenation when applied to vector types.
1273+ // The type of a unique vector is written as ~ [ int]
1274+ let more_numbers: ~ [ int] = numbers;
12691275
1270- ~~~~
1271- # enum Crayon { Almond, AntiqueBrass, Apricot,
1272- # Aquamarine, Asparagus, AtomicTangerine,
1273- # BananaMania, Beaver, Bittersweet };
1274- # impl Clone for Crayon {
1275- # fn clone(&self) -> Crayon {
1276- # *self
1277- # }
1278- # }
1276+ // The original ` numbers ` value can no longer be used, due to move semantics.
12791277
1280- let my_crayons = ~[Almond, AntiqueBrass, Apricot];
1281- let your_crayons = ~[BananaMania, Beaver, Bittersweet];
1278+ let mut string = ~ "fo";
1279+ string.push_char('o');
1280+ ~~~
12821281
1283- // Add two vectors to create a new one
1284- let our_crayons = my_crayons + your_crayons;
1282+ Slices are similar to fixed-size vectors, but the length is not part of the
1283+ type. They simply point into a block of memory and do not have ownership over
1284+ the elements.
12851285
1286- // .push_all() will append to a vector, provided it lives in a mutable slot
1287- let mut my_crayons = my_crayons;
1288- my_crayons.push_all(your_crayons);
1289- ~~~~
1286+ ~~~
1287+ // A slice
1288+ let xs = &[ 1, 2, 3] ;
12901289
1291- > ***Note:*** The above examples of vector addition use owned
1292- > vectors. Some operations on slices and stack vectors are
1293- > not yet well-supported. Owned vectors are often the most
1294- > usable.
1290+ // Slices have their type written as &[ int]
1291+ let ys: &[ int] = xs;
1292+
1293+ // Other vector types coerce to slices
1294+ let three = [ 1, 2, 3] ;
1295+ let zs: &[ int] = three;
1296+
1297+ // An unadorned string literal is an immutable string slice
1298+ let string = "foobar";
1299+
1300+ // A string slice type is written as &str
1301+ let view: &str = string.slice(0, 3);
1302+ ~~~
1303+
1304+ Mutable slices also exist, just as there are mutable references. However, there
1305+ are no mutable string slices. Strings are a multi-byte encoding (UTF-8) of
1306+ Unicode code points, so they cannot be freely mutated without the ability to
1307+ alter the length.
1308+
1309+ ~~~
1310+ let mut xs = [ 1, 2, 3] ;
1311+ let view = xs.mut_slice(0, 2);
1312+ view[ 0] = 5;
1313+
1314+ // The type of a mutable slice is written as &mut [ T]
1315+ let ys: &mut [ int] = &mut [ 1, 2, 3] ;
1316+ ~~~
12951317
12961318Square brackets denote indexing into a vector:
12971319
@@ -1319,103 +1341,12 @@ let score = match numbers {
13191341};
13201342~~~~
13211343
1322- The elements of a vector _inherit the mutability of the vector_,
1323- and as such, individual elements may not be reassigned when the
1324- vector lives in an immutable slot.
1325-
1326- ~~~ {.xfail-test}
1327- # enum Crayon { Almond, AntiqueBrass, Apricot,
1328- # Aquamarine, Asparagus, AtomicTangerine,
1329- # BananaMania, Beaver, Bittersweet };
1330- let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
1331-
1332- crayons[0] = Apricot; // ERROR: Can't assign to immutable vector
1333- ~~~
1334-
1335- Moving it into a mutable slot makes the elements assignable.
1336-
1337- ~~~
1338- # enum Crayon { Almond, AntiqueBrass, Apricot,
1339- # Aquamarine, Asparagus, AtomicTangerine,
1340- # BananaMania, Beaver, Bittersweet };
1341- let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
1342-
1343- // Put the vector into a mutable slot
1344- let mut mutable_crayons = crayons;
1345-
1346- // Now it's mutable to the bone
1347- mutable_crayons[0] = Apricot;
1348- ~~~
1349-
1350- This is a simple example of Rust's _ dual-mode data structures_ , also
1351- referred to as _ freezing and thawing_ .
1352-
1353- Strings are implemented with vectors of ` u8 ` , though they have a
1354- distinct type. They support most of the same allocation options as
1355- vectors, though the string literal without a storage sigil (for
1356- example, ` "foo" ` ) is treated differently than a comparable vector
1357- (` [foo] ` ). Whereas plain vectors are stack-allocated fixed-length
1358- vectors, plain strings are borrowed pointers to read-only (static)
1359- memory. All strings are immutable.
1360-
1361- ~~~
1362- // A plain string is a slice to read-only (static) memory
1363- let stack_crayons: &str = "Almond, AntiqueBrass, Apricot";
1364-
1365- // The same thing, but with the `&`
1366- let stack_crayons: &str = &"Aquamarine, Asparagus, AtomicTangerine";
1367-
1368- // A local heap (managed) string
1369- let local_crayons: @str = @"BananaMania, Beaver, Bittersweet";
1370-
1371- // An exchange heap (owned) string
1372- let exchange_crayons: ~str = ~"Black, BlizzardBlue, Blue";
1373- ~~~
1374-
1375- Both vectors and strings support a number of useful
1376- [ methods] ( #methods ) , defined in [ ` std::vec ` ]
1377- and [ ` std::str ` ] . Here are some examples.
1344+ Both vectors and strings support a number of useful [methods](#methods),
1345+ defined in [`std::vec`] and [`std::str`].
13781346
13791347[`std::vec`]: std/vec/index.html
13801348[`std::str`]: std/str/index.html
13811349
1382- ~~~
1383- # enum Crayon {
1384- # Almond, AntiqueBrass, Apricot,
1385- # Aquamarine, Asparagus, AtomicTangerine,
1386- # BananaMania, Beaver, Bittersweet
1387- # }
1388- # fn unwrap_crayon(c: Crayon) -> int { 0 }
1389- # fn eat_crayon_wax(i: int) { }
1390- # fn store_crayon_in_nasal_cavity(i: uint, c: Crayon) { }
1391- # fn crayon_to_str(c: Crayon) -> &str { "" }
1392-
1393- let crayons = [Almond, AntiqueBrass, Apricot];
1394-
1395- // Check the length of the vector
1396- assert!(crayons.len() == 3);
1397- assert!(!crayons.is_empty());
1398-
1399- // Iterate over a vector, obtaining a pointer to each element
1400- // (`for` is explained in the container/iterator tutorial)
1401- for crayon in crayons.iter() {
1402- let delicious_crayon_wax = unwrap_crayon(*crayon);
1403- eat_crayon_wax(delicious_crayon_wax);
1404- }
1405-
1406- // Map vector elements
1407- let crayon_names = crayons.map(|v| crayon_to_str(*v));
1408- let favorite_crayon_name = crayon_names[0];
1409-
1410- // Remove whitespace from before and after the string
1411- let new_favorite_crayon_name = favorite_crayon_name.trim();
1412-
1413- if favorite_crayon_name.len() > 5 {
1414- // Create a substring
1415- println(favorite_crayon_name.slice_chars(0, 5));
1416- }
1417- ~~~
1418-
14191350# Closures
14201351
14211352Named functions, like those we've seen so far, may not refer to local
0 commit comments