X-Git-Url: https://git.ralfj.de/rust-101.git/blobdiff_plain/4f61be32dd480f23a7fef05ee66c42ae27c980c6..8758d64fa600a64154978b245540e9e0c6af9db1:/src/part04.rs diff --git a/src/part04.rs b/src/part04.rs index f39df37..e7cf7f2 100644 --- a/src/part04.rs +++ b/src/part04.rs @@ -27,7 +27,7 @@ fn work_on_vector(v: Vec) { /* do something */ } fn ownership_demo() { let v = vec![1,2,3,4]; work_on_vector(v); - /* println!("The first element is: {}", v[0]); */ + /* println!("The first element is: {}", v[0]); */ /* BAD! */ } //@ Rust attaches additional meaning to the argument of `work_on_vector`: The function can assume //@ that it entirely *owns* `v`, and hence can do anything with it. When `work_on_vector` ends, @@ -68,7 +68,9 @@ fn vec_min(v: &Vec) -> Option { use std::cmp; let mut min = None; - for e in v { + // This time, we explicitly request an iterator for the vector `v`. The method `iter` borrows the vector + // it works on, and provides shared borrows of the elements. + for e in v.iter() { // In the loop, `e` now has type `&i32`, so we have to dereference it to obtain an `i32`. min = Some(match min { None => *e, @@ -102,9 +104,9 @@ fn shared_borrow_demo() { //@ As an example, consider a function which increments every element of a vector by 1. //@ The type `&mut Vec` is the type of mutable borrows of `vec`. Because the borrow is -//@ mutable, we can change `e` in the loop. +//@ mutable, we can use a mutable iterator, providing a mutable borrow of the elements. fn vec_inc(v: &mut Vec) { - for e in v { + for e in v.iter_mut() { *e += 1; } } @@ -114,10 +116,12 @@ fn mutable_borrow_demo() { /* let first = &v[0]; */ vec_inc(&mut v); vec_inc(&mut v); - /* println!("The first element is: {}", *first); */ + /* println!("The first element is: {}", *first); */ /* BAD! */ } //@ `&mut` is the operator to create a mutable borrow. We have to mark `v` as mutable in order to create such a -//@ borrow. Because the borrow passed to `vec_inc` only lasts as long as the function call, we can still call +//@ borrow: Even though we completely own `v`, Rust tries to protect us from accidentally mutating things. +//@ Hence owned variables that you intend to mutate, have to be annotated with `mut`. +//@ Because the borrow passed to `vec_inc` only lasts as long as the function call, we can still call //@ `vec_inc` on the same vector twice: The durations of the two borrows do not overlap, so we never have more //@ than one mutable borrow. However, we can *not* create a shared borrow that spans a call to `vec_inc`. Just try //@ enabling the commented-out lines, and watch Rust complain. This is because `vec_inc` could mutate @@ -139,4 +143,4 @@ fn mutable_borrow_demo() { // As it turns out, combined with the abstraction facilities of Rust, this is a very powerful mechanism // to tackle many problems beyond basic memory safety. You will see some examples for this soon. -//@ [index](main.html) | [previous](part03.html) | [next](part05.html) +//@ [index](main.html) | [previous](part03.html) | [raw source](https://www.ralfj.de/git/rust-101.git/blob_plain/HEAD:/workspace/src/part04.rs) | [next](part05.html)