Rust 将向量分解为变量并放弃所有权?

Rust 将向量分解为变量并放弃所有权?,rust,Rust,我有一个结构 struct Foo { foo1: String, foo2: String, foo3: String, foo4: String, // ... } 我想从一个向量创建一个Foo的实例 let x = vec!["a".to_string(), "b".to_string(), "c".to_string(), "d".to_string()]; match x.as_slice() { &[ref a, ref b,

我有一个结构

struct Foo {
    foo1: String,
    foo2: String,
    foo3: String,
    foo4: String,
    // ...
}
我想从一个向量创建一个
Foo
的实例

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!(),
}
我必须复制字符串吗?有没有更好的方法将向量分解为
a
b
c
d
以及转移所有权


实际上,我不介意
x
在解构后被完全销毁。所以我希望除了切片之外,还有一个向量模式匹配。目前看来,我们只能对切片进行解构。

解构切片是不稳定的,你不能移出切片,因为它只是一个借来的东西-如果你移出,那么
Vec
的解构器会做什么

变异向量是一种方法:

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);

我必须复制字符串吗

如果您愿意放弃解构,则不会。我是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,
        };
    }
}
这将向量(以及成员)的所有权转移到迭代器,然后
元组
适配器将值分块到元组中。我们取其中的第一个并构造值

如果不想放弃对整个向量的所有权,也可以使用
drain

if let Some((foo1, foo2, foo3, foo4)) = x.drain(..4).tuples().next() {
有没有更好的方法将向量分解为
a
b
c
d
以及转移所有权


不,除了迭代器之外,没有任何机制可以在不创建另一个
Vec
(或具有相同限制的另一种类型)的情况下拥有
Vec
的一部分所有权。

用于实验。另请参见和。可以
Vec::drain()
是否可以与切片分解相结合以提供move+destructure语义?@user4815162342无法移出切片,因为数据结构本身无法跟踪它移出的位置是否存在“洞”。由于
drain
提供了一个迭代器,如果您想保留
Vec
的话,可以将它与我的答案一起使用。@Shepmaster我是在回答答案中说您不能移出一个片段的部分。由于
drain()
是专门为将元素移出集合而设计的,因此我很好奇将
drain()
与切片分解相结合的可能性,可能中间有一种类型。您的答案当然可以,但它不使用切片分解。@user4815162342明白了。我的观点是,切片分解在切片上起作用,而你不能移出切片,因为它们总是代表一个借来的值,不管你要走哪条路才能到达那里。听起来你需要一些其他的解构技术(“vec解构”?)。@Shepmaster是的,我想我希望切片解构实际上是一个误称,它可以处理的不仅仅是切片。:)名称正确意味着您只能在
和[…]
内部使用
ref x
,至少对于非
复制类型,对吗?