如何在 Rust 中折叠向量的向量?

How to fold vector of vector in rust?

我有一个向量的向量,如下所示。

    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()
}

现在,我想要 fold 向量 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 函数的签名是正确的,因为它不想获得参数向量的所有权,并且它 returns 是一个新向量,因此所有权应该传递给来电者。

实际上,我尝试了所有可能的组合(add/remove & 从函数等),但无法使代码通过编译器。

你能告诉我我错过了什么,上面的代码有什么问题吗?谢谢。

fold 的第一个参数必须与其输出的类型相同。因此,您建议传递类型为 & Vec<u64>& m[0] 是行不通的,因为您希望折叠到 return Vec<u64>(通知值与借用值)。使用 m[0](不借用)将不起作用,因为您将尝试从稍后使用的向量(在迭代本身中)移动。

一种选择是从 m[0].clone() 作为初始值开始。显然,这确实涉及克隆,但无论如何您都需要以某种方式分配您的输出,所以您不能做得更好。这有效:

let s: Vec<u64> = m[1..].iter().fold(m[0].clone(), |acc, xs| add(& acc, xs));

无关紧要:我建议您将 add 更改为具有更通用的签名 fn add(xs: & [u64], ys: & [u64]) -> Vec<u64>。您仍然可以按原样使用它(因为 & Vec<u64> 强制转换为 & [u64]),但它更通用,因为其他类型也强制转换为 & [u64]