Vector method push_all not found for custom structure

So in this simple example

#![feature(collections)]

struct User {
    reference: String,
    email: String
}

fn main() {

    let rows = vec![
        vec!["abcd".to_string(), "test@test.com".to_string()],
        vec!["efgh".to_string(), "test1@test.com".to_string()],
        vec!["wfee".to_string(), "test2@test.com".to_string()],
        vec!["rrgr".to_string(), "test3@test.com".to_string()]
    ];
    let mut rows_mut: Vec<Vec<String>> = Vec::new();
    rows_mut.push_all(&rows);

    let mut users_mut: Vec<User> = Vec::new();
    let users = vec![
        User { reference: "ref1".to_string(), email: "test@test.com".to_string() },
        User { reference: "ref2".to_string(), email: "test1@test.com".to_string() }
    ];
    users_mut.push_all(&users);

}

      

I am getting the error

src/main.rs:24:12: 24:28 error: no method named `push_all` found for type `collections::vec::Vec<User>` in the current scope
src/main.rs:24  users_mut.push_all(&users);
                          ^~~~~~~~~~~~~~~~
error: aborting due to previous error

      

Why does it work for Vec<String>

but not for Vec<User>

? The only way in this case to repeat and add elements one by one?

+3


source to share


2 answers


Check out the definitionpush_all

:

impl<T> Vec<T> where T: Clone {
    fn push_all(&mut self, other: &[T]);
}

      

Adds all elements to the slice to Vec

.

Iterates over the slice other

, clones each item , and then adds it to that Vec

. The vector other

goes in order.

(Underline mine.)



Your type must implement Clone

because it clones every value. String

does; User

does not. You can add #[derive(Clone)]

to it.

If you want to use the original vector, you should use x.extend(y.into_iter())

that avoids the need to clone the values.

Of course, for this trivial case, if its purely a mut

ness difference , just add mut

to the original template (if its function argument works too, the bit before the colon in each argument, the template is like with let

, so fn foo(mut x: Vec<T>) { … }

works fine and is equivalent fn foo(x: Vec<T>) { let mut x = x; … }

.)

+6


source


Because if you go to the documentation forVec::push_all

and scroll up and a little, you will see this line:

impl<T: Clone> Vec<T>

      



This means that the following methods are only implemented for Vec<T>

when T

implements Clone

. In this case, it T

will User

, rather User

than implement Clone

. Therefore the method does not exist.

You can fix this problem by adding #[derive(Clone)]

before struct User {...}

.

+4


source







All Articles