在不取得所有权的情况下创建新的 Rc 实例

Creating new Rc instances without taking ownership

假设我有以下代码:

use std::rc::Rc;

struct Struct {}

struct Pair {
    first: Rc<Struct>,
    second: Rc<Struct>
}

fn pair_lists(vec:Vec<Struct>) -> Vec<Pair> {
    let mut pair = Vec::new();
    for i in 0..vec.len() {
        for j in i+1..vec.len() {
            let new_pair = Pair {
                first: Rc::new(vec[i]),
                second: Rc::new(vec[j])
            };
            pair.push(new_pair);
        }
    }
    pair
}

fn main() {
}

这不会编译,因为在函数 pair_lists 中,Rc::new 将取得 vec:

的所有权
error[E0507]: cannot move out of index of `Vec<Struct>`
  --> src/main.rs:15:32
   |
15 |                 first: Rc::new(vec[i]),
   |                                ^^^^^^ move occurs because value has type `Struct`, which does not implement the `Copy` trait

error[E0507]: cannot move out of index of `Vec<Struct>`
  --> src/main.rs:16:33
   |
16 |                 second: Rc::new(vec[j])
   |                                 ^^^^^^ move occurs because value has type `Struct`, which does not implement the `Copy` trait

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0507`.

但是,我不想通过复制 vec 的所有实例来创建开销;理想情况下,内存中的每个元素应该只有一个副本。

rust 的惯用方法是什么?

首先将 vec 转换为 Vec<Rc<Struct>>,然后从中克隆 Rc

fn pair_lists(vec:Vec<Struct>) -> Vec<Pair> {
    let vec: Vec<Rc<Struct>> = vec
        .into_iter()
        .map(Rc::new)
        .collect();

    let mut pair = Vec::new();
    for i in 0..vec.len() {
        for j in i+1..vec.len() {
            let new_pair = Pair {
                first: Rc::clone(&vec[i]),
                second: Rc::clone(&vec[j]),
            };
            pair.push(new_pair);
        }
    }
    pair
}

也可以使用 itertools crate 中的 .tuple_windows() 从 vec 创建对:

use itertools::Itertools;

fn pair_lists(vec:Vec<Struct>) -> Vec<Pair> {
    vec.into_iter()
        .map(Rc::new)
        .tuple_windows()
        .map(|(first, second)| Pair { first, second, })
        .collect()
}