如何将 Vec 解构为拥有所有权的变量?

col*_*ang 8 rust

我有一个结构

struct Foo {
    foo1: String,
    foo2: String,
    foo3: String,
    foo4: String,
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我想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!(),
}
Run Code Online (Sandbox Code Playgroud)

我必须复制字符串吗?有没有更好的方法将向量解构为a, b, c,d并转移所有权?

事实上,我不介意x解构后被彻​​底摧毁。所以我希望除了切片之外还有向量的模式匹配。目前看来我们只能解构切片。

She*_*ter 7

我必须复制字符串吗?

如果您愿意放弃解构,则不会。我是 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,
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

这会将向量(以及成员)的所有权转移给迭代器,然后tuples适配器将值分块到元组中。我们采用其中的第一个并构建值。

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

if let Some((foo1, foo2, foo3, foo4)) = x.drain(..4).tuples().next() {
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法将向量解构为a, b, c,d并转移所有权?

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