将矢量构造成变量并放弃所有权?

时间:2017-04-27 12:16:30

标签: 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, ref c, ref d] => {
        let foo = Foo {
            foo1: a.to_string(),
            foo2: b.to_string(),
            foo3: c.to_string(),
            foo4: d.to_string(),
        };

    },
    _ => unreachable!(),
}

我是否必须复制字符串?有没有更好的方法将向量解构为abcd以及转让所有权?

实际上,我不介意x在解构后被彻​​底摧毁。所以我希望除了切片之外还有一个矢量模式匹配。现在看来我们只能破坏切片。

2 个答案:

答案 0 :(得分:2)

  

我是否必须复制字符串?

如果你愿意放弃解构,那就不行了。我是itertools的忠实粉丝:

extern crate itertools;

use itertools::Itertools;

fn main() {
    let x = vec!["a".to_string(),
                 "b".to_string(),
                 "c".to_string(),
                 "d".to_string()];
    if let Some((a, b, c, d)) = x.into_iter().tuples().next() {
        let foo = Foo {
            foo1: a,
            foo2: b,
            foo3: c,
            foo4: d,
        };
    }
}

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

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

if let Some((a, b, c, d)) = x.drain(0..4).tuples().next() {
  

有没有更好的方法将矢量解构为a,b,c,d以及转让所有权?

不,这些限制没有更好的方法。正如编译器告诉你的那样,切片模式不是稳定Rust的一部分:

  

错误:切片模式语法是实验性的(参见问题#23121)

我确定有很多原因,但有一个原因可能是这样的事情是不允许的。

答案 1 :(得分:1)

解构切片不稳定,你不能移出切片因为它只是借用 - 如果你搬出去了,那么Vec&#39 ;析构函数吗?

改变向量是这里的方法:

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