什么是非破坏性地将值附加到向量的惯用方法?

时间:2017-07-13 21:10:48

标签: vector rust

我有一个程序,其中我fold在一个字符串向量上,并递增一个值并构建另一个向量。像这样:

struct Widget { foo: isize, text: &'static str }
let foos = vec!["a", "b", "c"];
let (final, ws) = foos.iter().fold((0, widgets), |(x, ws), text| {
    (x+1, Widget { foo: x, text: text })
});

上述代码的问题是我需要新小部件追加到ws,而不是返回新的小部件来代替ws。为此,我需要一种非破坏性地将值附加到向量的方法。这是我正在寻找的功能的大致签名:

fn append<T>(vec: Vec<T>, item: T) -> Vec<T>

我似乎无法找到这样的功能。看起来像这样(或者作为Vec上的方法)对Rust来说是非常惯用的,但它不存在。有没有其他方法可以更具惯用地实现它,或者是否有类似上面的函数?

1 个答案:

答案 0 :(得分:2)

  

非破坏性地将值附加到矢量

这是不可能的。修改矢量...修改它。你无法解决这个问题。您可以选择向量clone,这样可以避免改变原始向量。但是,您仍然需要改变克隆:

let things = vec![1];
let things2 = {
    let mut tmp = things.clone();
    tmp.push(2);
    tmp
};

如果您已完成原始矢量,则可以重复使用它:

let things = vec![1];
let things2 = {
    let mut tmp = things;
    tmp.push(2);
    tmp
};

这可以提取到您想要的功能签名中:

fn append(vec: Vec<i32>, item: i32) -> Vec<i32> {
    let mut vec = vec;
    vec.push(item);
    vec
};

哪个是惯用的,但等效地写为

fn append(mut vec: Vec<i32>, item: i32) -> Vec<i32> {
    vec.push(item);
    vec
};

let things = vec![1];
let things2 = append(things.clone(), 2);
let things2 = append(things, 2);
  

似乎这个(或者作为Vec上的方法)对于Rust来说是非常惯用的

不是 - 要拥有此方法签名,您必须拥有Vec。更常见的是只有Vec的可变引用,它提供了一组不同的功能。

有一些关于为Add实施Vec的讨论,可能允许let things2 = things + 2这样的内容,但我不知道这样做了。

为了它的价值,我将你的代码编写为:

let foos = ["a", "b", "c"];

let ws: Vec<_> = foos.iter()
    .enumerate()
    .map(|(i, text)| Widget { foo: i as isize, text })
    .collect();