Reputation: 6298
I am following the second edition of the TRPL book (second edition) and am a little confused by one of the tasks. At the end of section 10.2 (Traits) I am asked to reimplement the largest
function using the Clone
trait. (Note that at this point I have not learned anything about lifetimes yet.) I implemented the following
fn largest<T: PartialOrd + Clone>(list: &[T]) -> &T {
let l = list.clone();
let mut largest = &l[0];
for item in l {
if item > &largest {
largest = item;
}
}
largest
}
This returns a reference to an item of the cloned list. And, lo and behold, it compiles. Why is this not a dangling reference (as described in section 4.2)?
As far as I understand it, largest
contains a reference to an item of a (cloned) copy of list
, but should l
not go out of scope and thus invalidate the reference after largest
has finished?
Upvotes: 3
Views: 150
Reputation: 299890
Because l
does not have the type you think it does:
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let l: &[T] = list.clone();
let mut largest = &l[0];
for item in l {
if item > &largest {
largest = item;
}
}
largest
}
l
is a reference too, cloning a slice actually just returns the slice itself, with the same lifetime.
Therefore it's perfectly fine to take references into the slice, and your return value borrows the original slice.
Upvotes: 8