So in this simple example
#![feature(collections)]
struct User {
reference: String,
email: String
}
fn main() {
let rows = vec![
vec!["abcd".to_string(), "[email protected]".to_string()],
vec!["efgh".to_string(), "[email protected]".to_string()],
vec!["wfee".to_string(), "[email protected]".to_string()],
vec!["rrgr".to_string(), "[email protected]".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: "[email protected]".to_string() },
User { reference: "ref2".to_string(), email: "[email protected]".to_string() }
];
users_mut.push_all(&users);
}
I'm getting an 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>? Is the only way in this case to iterate and add elements one by one?
Look at the definition of push_all:
impl<T> Vec<T> where T: Clone {
fn push_all(&mut self, other: &[T]);
}
Appends all elements in a slice to the
Vec.Iterates over the slice
other, clones each element, and then appends it to thisVec. Theothervector is traversed in-order.
(Emphasis mine.)
Your type must implement Clone because it clones each value. String does; User doesn’t. You can add #[derive(Clone)] to it.
If you are willing to consume the source vector, you should use x.extend(y.into_iter()) which avoids needing to clone the values.
Of course, for this trivial case if it’s purely the difference in mutness, just add the mut in the initial pattern (if it’s a function argument this works too, the bit before the colon in each argument is a pattern, like with let, so fn foo(mut x: Vec<T>) { … } works fine and is equivalent to fn foo(x: Vec<T>) { let mut x = x; … }.)
Because, if you go to the documentation for Vec::push_all and scroll up and little, you'll 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, T would be User, and User does not implement Clone. Therefore, the method does not exist.
You can solve this by adding #[derive(Clone)] before struct User {...}.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With