Reputation: 1000
I'm trying to accomplish an exercise "left to the reader" in the 2018 Rust book. The example they have, 10-15, uses the Copy
trait. However, they recommend implementing the same without Copy
and I've been really struggling with it.
Without Copy
, I cannot use largest = list[0]
. The compiler recommends using a reference instead. I do so, making largest
into a &T
. The compiler then complains that the largest
used in the comparison is a &T
, not T
, so I change it to *largest
to dereference the pointer. This goes fine, but then stumbles on largest = item
, with complaints about T
instead of &T
. I switch to largest = &item
. Then I get an error I cannot deal with:
error[E0597]: `item` does not live long enough
--> src/main.rs:6:24
|
6 | largest = &item;
| ^^^^ borrowed value does not live long enough
7 | }
8 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 1:1...
I do not understand how to lengthen the life of this value. It lives and dies in the list.iter()
. How can I extend it while still only using references?
Here is my code for reference:
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for &item in list.iter() {
if item > *largest {
largest = &item;
}
}
largest
}
Upvotes: 3
Views: 367
Reputation: 65832
When you write for &item
, this destructures each reference returned by the iterator, making the type of item
T
. You don't want to destructure these references, you want to keep them! Otherwise, when you take a reference to item
, you are taking a reference to a local variable, which you can't return because local variables don't live long enough.
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
Note also how we can compare references directly, because references to types implementing PartialOrd
also implement PartialOrd
, deferring the comparison to their referents (i.e. it's not a pointer comparison, unlike for raw pointers).
Upvotes: 9