Might anybody be able to demonstrate a working implementation of the Clone-based solution it refers to, on https://play.rust-lang.org/, please? Was surprised to not be able to locate one with a Google search.
I've successfully implemented the other solutions - but hit some borrow/move errors I couldn't hack my way out of for this one. I'd love to move forward with the book without losing that learning experience! Any help would be very much appreciated, thanks!
Apparently just asking the question and walking away from the computer momentarily was sufficient for me to devise the solution. I'm now struggling to work out why I even struggled in the first place!
Here for anybody else in future that is similarly interested: Rust Playground
The most straightforward changes would be ... pretty much the ones you made, yeah. There is one change I would suggest. Instead of:
let i = item.clone();
if i > largest {
largest = i;
}
You could do:
if item > &largest {
largest = item.clone();
}
To avoid some clones.
I believe that's what the book was suggesting, and that's fine for practice. However, it's not a great approach in general because we end up potentially cloning all over the place. The second suggestion is a better one, make a largest_ref that returns a &T instead. Then you could have:
Appreciate the elaboration @quinedot. That advanced my understanding of moving. Specifically: reminding me that moving doesn't even happen in an operation such as >, when the underlying value is not being re-assigned to a variable - of course!
It depends on how comfortable you are with references, but I would skip the Clone requirement by just returning a reference to the largest item.
fn largest<T>(items: &[T]) -> &T
where
T: PartialOrd,
{
// TODO: Handle empty lists properly
assert!(!items.is_empty());
let mut largest = &items[0];
// Note: Start at 1 because we don't need to compare the 0'th item
// with itself
for item in &items[1..] {
if item > largest {
largest = item;
}
}
largest
}
I'm at the same point in the book and I have a question about his implementation. I wanted to write a method that returned a reference to the element of the list, as you do. My first attempt was similar to yours except I wrote this for loop:
for &elem in list {
if elem > largest_elem {
largest_elem = elem;
}
}
This code doesn't compile because elem is of type T and largest_elem is of type &T. I eventually found out that I could solve the problem writing:
for elem in list {
if elem > largest_elem {
largest_elem = elem;
}
}
but this doesn't make sense to me, why does calling for &elem in list create an elem of type T while for elem in list results in an elem of type &T?, shouldn't it be the opposite?