I want to write a function that takes in an array with any type in it and returns the last element of the array, so I've tried:
fn main() {
let v = ["a", "b"];
println!("{}", last(&v));
}
fn last<T: Clone>(slice: &[T]) -> &T {
&slice[slice.len()-1]
}
and that seems to work, but when I apply a small adjustment:
fn main() {
let v = ["a", "b"];
println!("{}", last(&v));
}
fn last<T: Clone>(slice: &[T]) -> T {
&slice[slice.len()-1]
}
Then I'm met with:
error[E0308]: mismatched types
--> <anon>:9:5
|
9 | &slice[n-1]
| ^^^^^^^^^^^ expected type parameter, found &T
|
= note: expected type `T`
found type `&T`
How do I convert the &T
to just T
?
In your first example, you are returning a &T
and taking a reference to something, so the value and the types match:
fn last<T: Clone>(slice: &[T]) -> &T {
// ^^
&slice[slice.len()-1]
// ^
}
But, then you said you weren't going to return a reference anymore, but didn't change the implementation.
fn last<T: Clone>(slice: &[T]) -> T {
// ^
&slice[slice.len()-1]
// ^
}
T
, &T
and &mut T
are all different types from each other! This means it's the same as this "small adjustment":
fn foo() -> i32 { 42 } // Before
fn foo() -> bool { 42 } // After
Let's drop the &
from the body:
fn last<T: Clone>(slice: &[T]) -> T {
slice[slice.len()-1]
}
Oops...
error[E0507]: cannot move out of indexed content
--> src/main.rs:4:9
|
4 | slice[slice.len()-1]
| ^^^^^^^^^^^^^^^^^^^^ cannot move out of indexed content
This is well explained in What does "cannot move out of indexed content" mean?.
The answer to your question is: there's no one right way. There are three broad possibilities:
The type implements Copy
and the compiler automatically dereferences it for you:
fn last_copy<T: Copy>(slice: &[T]) -> T {
slice[slice.len()-1]
}
The type implements Clone
, so you can explicitly call Clone
to duplicate it:
fn last_clone<T: Clone>(slice: &[T]) -> T {
slice[slice.len()-1].clone()
}
There might also be other methods on your type that do something similar.
You don't. Sometimes, if you have a reference, you can't get a corresponding value. In those cases, you need to re-evaluate your design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With