我有一个如下的二维向量。
let m: Vec<Vec<u64>> = vec![
vec![1, 2, 3, 4, 5],
vec![1, 2, 3, 4, 5],
vec![1, 2, 3, 4, 5],
vec![1, 2, 3, 4, 5],
vec![1, 2, 3, 4, 5]
];
增加一个函数add
,旨在将两个向量的每个元素相加。
fn add(xs: &Vec<u64>, ys: &Vec<u64>) -> Vec<u64> {
xs.iter().zip(ys.iter()).map(|(x, y)| x + y).collect()
}
现在,我想要对存储向量的向量 m
进行折叠操作。
我尝试过的方法是:
let s: Vec<u64> = m[1..]
.iter()
.fold(m[0], |acc, xs| add(&acc, xs));
但是这段代码无法通过编译器。
|
16 | .fold(m[0], |acc, xs| add(&acc, xs));
| ^^^^ move occurs because value has type `Vec<u64>`, which does not implement the `Copy` trait
我尝试了使用&
来前置,但编译器仍然拒绝:
|
16 | .fold(&m[0], |acc, xs| add(&acc, xs));
| ^^^^^ expected struct `Vec`, found `&Vec<u64>`
|
= note: expected struct `Vec<u64>`
found reference `&Vec<u64>`
help: consider removing the borrow
|
16 - .fold(&m[0], |acc, xs| add(&acc, xs));
16 + .fold(m[0], |acc, xs| add(&acc, xs));
|
我认为add
函数的签名是正确的,因为它不想接管参数向量的所有权,并返回一个新的向量,因此所有权应该传递给调用者。
实际上,我尝试了各种可能的组合(添加/删除函数中的&
等),但无法使代码通过编译器。
你能告诉我错过了什么,上述代码有什么问题吗?谢谢。
fold
的第一个参数必须与其输出类型相同。因此,传递类型为& Vec<u64>
的& m[0]
将不起作用,因为您希望折叠返回Vec<u64>
。一种选择是以m[0].clone()
作为初始值开始。显然,这涉及到克隆,但无论如何,您都需要分配输出。 - gspr&Vec<T>
是一种反模式:请使用&[T]
。 - Chayim Friedman