pointers - Cannot move out of borrowed content when borrowing a generic type -


i have program more or less looks 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, call method on struct test borrows value. call method on same struct, passing obtained value.

this example works fine. now, when make content of main generic, doesn't work anymore.

fn generic_main<t>(t: test<t>) {     let x = t.get_first();     t.do_something_with_x(*x); } 

then following error:

error: cannot move out of borrowed content

src/main.rs:14 let raw_x = *x;

i'm not sure why happening. can explain me why test<i32> isn't borrowed when calling get_first while test<t> is?

the short answer i32 implements copy trait, t not. if use fn generic_main<t: copy>(t: test<t>), immediate problem fixed.

the longer answer copy special trait means values can copied copying bits. types i32 implement copy. types string not implement copy because, example, requires heap allocation. if copied string copying bits, you'd end 2 string values pointing same chunk of memory. not (it's unsafe!).

therefore, giving t copy bound quite restrictive. less restrictive bound t: clone. clone trait similar copy (in copies values), it's done more "copying bits." example, string type implement clone creating new heap allocation underlying memory.

this requires change how generic_main written:

fn generic_main<t: clone>(t: test<t>) {     let x = t.get_first();     t.do_something_with_x(x.clone()); } 

alternatively, if don't want have either clone or copy bounds, change do_something_with_x method take reference t rather owned t:

impl<t> test<t> {     // other methods elided      fn do_something_with_x(&self, x: &t) {         // irrelevant     } } 

and generic_main stays same, except 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 copy in docs. there nice examples, including how implement copy own types.


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

jquery - javascript onscroll fade same class but with different div -