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?
source to share
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 thatVec
. The vectorother
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; … }
.)
source to share
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 {...}
.
source to share