I have a program that more or less looks like this
struct Test {
vec: Vec
}
impl Test {
fn get_first(&self) -
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.