问题
I have a struct
struct Foo {
foo1: String,
foo2: String,
foo3: String,
foo4: String,
// ...
}
I would like to create an instance of Foo from a vector.
let x = vec!["a".to_string(), "b".to_string(), "c".to_string(), "d".to_string()];
match x.as_slice() {
&[ref a, ref b, ref c, ref d] => {
let foo = Foo {
foo1: a.to_string(),
foo2: b.to_string(),
foo3: c.to_string(),
foo4: d.to_string(),
};
},
_ => unreachable!(),
}
Do I have to copy the strings? Is there any better way to destructure the vector into a, b, c, d as well as transferring the ownership?
Actually, I don't mind x is completely destroyed after the destructuring. So I hope there is a pattern match for vectors apart from slices as well. For now it seems we can only destructure slices.
回答1:
Do I have to copy the strings?
Not if you are willing to give up destructuring. I'm a big fan of itertools:
use itertools::Itertools; // 0.8.2
fn main() {
let x = vec![
"a".to_string(),
"b".to_string(),
"c".to_string(),
"d".to_string(),
];
if let Some((foo1, foo2, foo3, foo4)) = x.into_iter().tuples().next() {
let foo = Foo {
foo1,
foo2,
foo3,
foo4,
};
}
}
This transfers ownership of the vector (and thus the members) to an iterator, then the tuples adapter chunks up the values into a tuple. We take the first one of those and construct the value.
You could also use drain if you didn't want to give up ownership of the entire vector:
if let Some((foo1, foo2, foo3, foo4)) = x.drain(..4).tuples().next() {
Is there any better way to destructure the vector into
a,b,c,das well as transferring the ownership?
No, there is no mechanism to take ownership of a part of a Vec without creating another Vec (or another type that has the same limits) except for an iterator.
回答2:
Destructuring slices isn't stable, and you can't move out of a slice because it's just a borrow — if you moved out, what would the Vec's destructor do?
Mutating the vector is the way to go here:
let mut x = vec!["a".to_string(), "b".to_string(), "c".to_string(), "d".to_string()];
let foo = Foo {
foo4: x.pop().unwrap(),
foo3: x.pop().unwrap(),
foo2: x.pop().unwrap(),
foo1: x.pop().unwrap(),
};
println!("{:?}", foo);
playground
来源:https://stackoverflow.com/questions/43657570/destructure-a-vector-into-variables-and-give-away-ownership