创建新的Rc实例而不获取所有权



假设我有以下代码:

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的所有实例来创建开销;理想情况下,每个元素在内存中应该只有一个副本。

实现这一点的惯用方法是什么?

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

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
}

从vec创建pair也可以通过使用itertoolscrate中的.tuple_windows()来完成:

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

最新更新