Cannot move out of borrowed content when borrowing a generic type
pointers, rust
Solution
The short answer is that `i32` implements the `Copy` trait, but `T` does not. If you use `fn generic_main<T: Copy>(t: Test<T>)`, then your immediate problem is fixed.
The longer answer is that `Copy` is a special trait which means values can be copied by simply copying bits. Types like `i32` implement `Copy`. Types like `String` do not implement `Copy` because, for example, it requires a heap allocation. If you copied a `String` just by copying bits, you'd end up with two `String` values pointing to the same chunk of memory. That would not be good (it's unsafe!).
Therefore, giving your `T` a `Copy` bound is quite restrictive. A less restrictive bound would be `T: Clone`. The `Clone` trait is similar to `Copy` (in that it copies values), but it's usually done by more than just "copying bits." For example, the `String` type will implement `Clone` by creating a new heap allocation for the underlying memory.
This requires you to change how your `generic_main` is written:
fn generic_main<T: Clone>(t: Test<T>) {
let x = t.get_first();
t.do_something_with_x(x.clone());
}
Alternatively, if you don't want to have either the `Clone` or `Copy` bounds, then you could change your `do_something_with_x` method to take a reference to `T` rather than an owned `T`:
impl<T> Test<T> {
// other methods elided
fn do_something_with_x(&self, x: &T) {
// Irrelevant
}
}
And your `generic_main` stays mostly the same, except you don't dereference `x`:
fn generic_main<T>(t: Test<T>) {
let x = t.get_first();
t.do_something_with_x(x);
}
You can read more about `Copy` in the docs. There are some nice examples, including how to implement `Copy` for your own types.
Problem
I have a program that more or less looks like this ``` struct Test<T> { vec: Vec<T> } impl<T> Test<T> { fn get_first(&self) -> &T { &self.vec[0] } fn do_something_with_x(&self, x: T) { // Irrelevant } } fn main() { let t = Test { vec: vec![1i32, 2, 3] }; let x = t.get_first(); t.do_something_with_x(*x); } ``` Basically, we call a method on the struct `Test` that borrows some value. Then we call another method on the same struct, passing the previously obtained value. This example works perfectly fine. Now, when we make the content of `main` generic, it doesn't work anymore. ``` fn generic_main<T>(t: Test<T>) { let x = t.get_first(); t.do_something_with_x(*x); } ``` Then I get the following error: error: cannot move out of borrowed content src/main.rs:14 let raw_x = *x; I'm not completely sure why this is happening. Can someone explain to me why `Test<i32>` isn't borrowed when calling `get_first` while `Test<T>` is?