我有一个程序,其中我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来说是非常惯用的,但它不存在。有没有其他方法可以更具惯用地实现它,或者是否有类似上面的函数?
答案 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();