@@ -1496,87 +1496,102 @@ low-level details matter, they really matter. Just remember that `String`s
1496
1496
allocate memory and control their data, while ` &str ` s are a reference to
1497
1497
another string, and you'll be all set.
1498
1498
1499
- # Vectors
1499
+ # Arrays, Vectors, and Slices
1500
1500
1501
- Like many programming languages, Rust has a list type for when you want a list
1502
- of things. But similar to strings, Rust has different types to represent this
1503
- idea: ` Vec<T> ` (a 'vector'), ` [T, .. N] ` (an 'array'), and ` &[T] ` (a 'slice').
1504
- Whew!
1501
+ Like many programming languages, Rust has list types to represent a sequence of
1502
+ things. The most basic is the ** array** , a fixed-size list of elements of the
1503
+ same type. By default, arrays are immutable.
1505
1504
1506
- Vectors are similar to ` String ` s: they have a dynamic length, and they
1507
- allocate enough memory to fit. You can create a vector with the ` vec! ` macro:
1505
+ ``` {rust}
1506
+ let a = [1i, 2i, 3i];
1507
+ let mut m = [1i, 2i, 3i];
1508
+ ```
1509
+
1510
+ You can create an array with a given number of elements, all initialized to the
1511
+ same value, with ` [val, ..N] ` syntax. The compiler ensures that arrays are
1512
+ always initialized.
1508
1513
1509
1514
``` {rust}
1510
- let nums = vec![1i, 2i, 3i];
1515
+ let a = [0i, ..20]; // Shorthand for array of 20 elements all initialized to 0
1511
1516
```
1512
1517
1513
- Notice that unlike the ` println! ` macro we've used in the past, we use square
1514
- brackets (` [] ` ) with ` vec! ` . Rust allows you to use either in either situation,
1515
- this is just convention.
1518
+ Arrays have type ` [T,..N] ` . We'll talk about this ` T ` notation later, when we
1519
+ cover generics.
1516
1520
1517
- You can create an array with just square brackets:
1521
+ You can get the number of elements in an array ` a ` with ` a.len() ` , and use
1522
+ ` a.iter() ` to iterate over them with a for loop. This code will print each
1523
+ number in order:
1518
1524
1519
1525
``` {rust}
1520
- let nums = [1i, 2i, 3i];
1521
- let nums = [1i, ..20]; // Shorthand for an array of 20 elements all initialized to 1
1526
+ let a = [1i, 2, 3]; // Only the first item needs a type suffix
1527
+
1528
+ println!("a has {} elements", a.len());
1529
+ for e in a.iter() {
1530
+ println!("{}", e);
1531
+ }
1522
1532
```
1523
1533
1524
- So what's the difference? An array has a fixed size, so you can't add or
1525
- subtract elements:
1534
+ You can access a particular element of an array with ** subscript notation** :
1526
1535
1527
- ``` {rust,ignore}
1528
- let mut nums = vec![1i, 2i, 3i];
1529
- nums.push(4i); // works
1536
+ ``` {rust}
1537
+ let names = ["Graydon", "Brian", "Niko"];
1530
1538
1531
- let mut nums = [1i, 2i, 3i];
1532
- nums.push(4i); // error: type `[int, .. 3]` does not implement any method
1533
- // in scope named `push`
1539
+ println!("The second name is: {}", names[1]);
1534
1540
```
1535
1541
1536
- The ` push() ` method lets you append a value to the end of the vector. But
1537
- since arrays have fixed sizes, adding an element doesn't make any sense.
1538
- You can see how it has the exact type in the error message: ` [int, .. 3] ` .
1539
- An array of ` int ` s, with length 3.
1542
+ Subscripts start at zero, like in most programming languages, so the first name
1543
+ is ` names[0] ` and the second name is ` names[1] ` . The above example prints
1544
+ ` The second name is: Brian ` . If you try to use a subscript that is not in the
1545
+ array, you will get an error: array access is bounds-checked at run-time. Such
1546
+ errant access is the source of many bugs in other systems programming
1547
+ languages.
1540
1548
1541
- Similar to ` &str ` , a slice is a reference to another array. We can get a
1542
- slice from a vector by using the ` as_slice() ` method:
1549
+ A ** vector** is a dynamic or "growable" array, implemented as the standard
1550
+ library type [ ` Vec<T> ` ] ( std/vec/ ) (we'll talk about what the ` <T> ` means
1551
+ later). Vectors are to arrays what ` String ` is to ` &str ` . You can create them
1552
+ with the ` vec! ` macro:
1543
1553
1544
1554
``` {rust}
1545
- let vec = vec![1i, 2i, 3i];
1546
- let slice = vec.as_slice();
1555
+ let v = vec![1i, 2, 3];
1547
1556
```
1548
1557
1549
- All three types implement an ` iter() ` method, which returns an iterator. We'll
1550
- talk more about the details of iterators later, but for now, the ` iter() ` method
1551
- allows you to write a ` for ` loop that prints out the contents of a vector, array,
1552
- or slice:
1558
+ (Notice that unlike the ` println! ` macro we've used in the past, we use square
1559
+ brackets ` [] ` with ` vec! ` . Rust allows you to use either in either situation,
1560
+ this is just convention.)
1553
1561
1554
- ``` {rust}
1555
- let vec = vec![1i, 2i, 3i];
1562
+ You can get the length of, iterate over, and subscript vectors just like
1563
+ arrays. In addition, (mutable) vectors can grow automatically:
1556
1564
1557
- for i in vec.iter() {
1558
- println!("{}", i);
1559
- }
1565
+ ``` {rust}
1566
+ let mut nums = vec![1i, 2, 3];
1567
+ nums.push(4);
1568
+ println!("The length of nums is now {}", nums.len()); // Prints 4
1560
1569
```
1561
1570
1562
- This code will print each number in order, on its own line .
1571
+ Vectors have many more useful methods .
1563
1572
1564
- You can access a particular element of a vector, array, or slice by using
1565
- ** subscript notation** :
1573
+ A ** slice** is a reference to (or "view" into) an array. They are useful for
1574
+ allowing safe, efficient access to a portion of an array without copying. For
1575
+ example, you might want to reference just one line of a file read into memory.
1576
+ By nature, a slice is not created directly, but from an existing variable.
1577
+ Slices have a length, can be mutable or not, and in many ways behave like
1578
+ arrays:
1566
1579
1567
1580
``` {rust}
1568
- let names = ["Graydon", "Brian", "Niko"];
1581
+ let a = [0i, 1, 2, 3, 4];
1582
+ let middle = a.slice(1, 4); // A slice of a: just the elements [1,2,3]
1569
1583
1570
- println!("The second name is: {}", names[1]);
1584
+ for e in middle.iter() {
1585
+ println!("{}", e); // Prints 1, 2, 3
1586
+ }
1571
1587
```
1572
1588
1573
- These subscripts start at zero, like in most programming languages, so the
1574
- first name is ` names[0] ` and the second name is ` names[1] ` . The above example
1575
- prints ` The second name is: Brian ` .
1589
+ You can also take a slice of a vector, ` String ` , or ` &str ` , because they are
1590
+ backed by arrays. Slices have type ` &[T] ` , which we'll talk about when we cover
1591
+ generics .
1576
1592
1577
- There's a whole lot more to vectors, but that's enough to get started. We have
1578
- now learned all of the most basic Rust concepts. We're ready to start building
1579
- our guessing game, but we need to know how to do one last thing first: get
1593
+ We have now learned all of the most basic Rust concepts. We're ready to start
1594
+ building our guessing game, we just need to know one last thing: how to get
1580
1595
input from the keyboard. You can't have a guessing game without the ability to
1581
1596
guess!
1582
1597
0 commit comments