@@ -1240,58 +1240,80 @@ The indexing operator (`[]`) also auto-dereferences.
1240
1240
1241
1241
# Vectors and strings
1242
1242
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.
1247
1253
1248
1254
~~~
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;
1257
1258
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
+ ~~~
1260
1262
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.
1263
1266
1264
- // An exchange heap (owned) vector of crayons
1265
- let exchange_crayons: ~ [ Crayon] = ~ [ Black, BlizzardBlue, Blue] ;
1266
1267
~~~
1268
+ // A dynamically sized vector (unique vector)
1269
+ let mut numbers = ~ [ 1, 2, 3] ;
1270
+ numbers.push(4);
1271
+ numbers.push(5);
1267
1272
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;
1269
1275
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.
1279
1277
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
+ ~~~
1282
1281
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.
1285
1285
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] ;
1290
1289
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
+ ~~~
1295
1317
1296
1318
Square brackets denote indexing into a vector:
1297
1319
@@ -1319,103 +1341,12 @@ let score = match numbers {
1319
1341
};
1320
1342
~~~~
1321
1343
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`].
1378
1346
1379
1347
[`std::vec`]: std/vec/index.html
1380
1348
[`std::str`]: std/str/index.html
1381
1349
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
-
1419
1350
# Closures
1420
1351
1421
1352
Named functions, like those we've seen so far, may not refer to local
0 commit comments