Cannot move out of borrowed content when borrowing a generic type

后端 未结 1 1760
攒了一身酷
攒了一身酷 2020-12-07 02:24

I have a program that more or less looks like this

struct Test {
    vec: Vec
}

impl Test {
    fn get_first(&self) -         


        
相关标签:
1条回答
  • 2020-12-07 03:09

    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.

    0 讨论(0)
提交回复
热议问题