}
}
-// Now we can write `vec_min`. However, in order to make it type-check, we have to make a full (deep) copy of e
-// by calling `clone()`.
+// Now we can write `vec_min`.
fn vec_min(v: &Vec<BigInt>) -> Option<BigInt> {
let mut min: Option<BigInt> = None;
+ // If `v` is a shared borrowed vector, then the default for iterating over it is to call `iter`, the iterator that borrows the elements.
for e in v {
- let e = e.clone(); /*@*/
+ let e = e.clone();
min = Some(match min { /*@*/
None => e, /*@*/
Some(n) => e.min_try1(n) /*@*/
}
min
}
-//@ Now, what's happening here? Why do we have to clone `e`, and why did we not
+//@ Now, what's happening here? Why do we have to to make a full (deep) copy of `e`, and why did we not
//@ have to do that in our previous version?
//@
//@ The answer is already hidden in the type of `vec_min`: `v` is just borrowed, but
//@ `e.clone()`, Rust will complain "Cannot move out of borrowed content". That's because
//@ `e` is a `&BigInt`. Assigning `min = Some(*e)` works just like a function call: Ownership of the
//@ underlying data is transferred from where `e` borrows from to `min`. But that's not allowed, since
-//@ we just borrowed `e`, so we cannot empty it! We can, however, call `clone()` on it. Then we own
-//@ the copy that was created, and hence we can store it in `min`.<br/>
-//@ Of course, making such a full copy is expensive, so we'd like to avoid it. We'll some to that in the next part.
+//@ we just borrowed `e`, so we cannot empty it! We can, however, call `clone` on it. Then we own
+//@ the copy that was created, and hence we can store it in `min`. <br/>
+//@ Of course, making such a full copy is expensive, so we'd like to avoid it. We'll come to that in the next part.
// ## `Copy` types
//@ But before we go there, I should answer the second question I brought up above: Why did our old `vec_min` work?
//@ ## An operational perspective
//@ Instead of looking at what happens "at the surface" (i.e., visible in Rust), one can also explain
-//@ ownership passing and how `Copy` and `Clone` fit in by looking at what happens on the machine.<br/>
+//@ ownership passing and how `Copy` and `Clone` fit in by looking at what happens on the machine. <br/>
//@ When Rust code is executed, passing a value (like `i32` or `Vec<i32>`) to a function will always
//@ result in a shallow copy being performed: Rust just copies the bytes representing that value, and
//@ considers itself done. That's just like the default copy constructor in C++. Rust, however, will
//@ `Clone`. This makes the cost explicit.
// ## Lifetimes
-//@ To fix the performance problems of `vec_min`, we need to avoid using `clone()`. We'd like
+//@ To fix the performance problems of `vec_min`, we need to avoid using `clone`. We'd like
//@ the return value to not be owned (remember that this was the source of our need for cloning), but *borrowed*.
//@ The function `head` demonstrates how that could work: It borrows the first element of a vector if it is non-empty.