簡體   English   中英

如何在 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 function 意在添加兩個向量的每個元素。

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

我嘗試了 prepend &但編譯器仍然拒絕:

   |
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 function 的簽名是正確的,因為它不想擁有 arguments 向量的所有權,它返回一個新向量,因此所有權應該傳遞給調用者。

實際上,我嘗試了所有可能的組合(從 function 等中添加/刪除& ),但無法使代碼通過編譯器。

你能告訴我我錯過了什么,上面的代碼有什么問題嗎? 謝謝。

fold的第一個參數必須與其 output 的類型相同。 因此,您建議傳遞具有& Vec<u64>類型的& m[0]的建議將不起作用,因為您希望折疊返回Vec<u64> (注意值與借用值)。 並且使用m[0] (不借用)將不起作用,因為您將嘗試從稍后使用的向量(在迭代本身中)移動。

一種選擇是從m[0].clone()作為初始值開始。 顯然,這確實涉及克隆,但是無論如何您都需要以某種方式分配 output ,所以您不能做得更好。 這有效:

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]

使用類似的東西

let first = m.pop().unwrap();
let s: Vec<u64> = m
        .iter()
        .fold(first, |acc, xs| add(&acc, xs));

這避免了克隆第一個參數。 它假定操作的順序無關緊要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM