【发布时间】:2015-09-22 12:04:40
【问题描述】:
TL;DR如何在引用共享底层数据的泛型类型上构建数据结构?
这个问题是关于 Rust 中的语义和良好的数据建模。下面的代码是对我的问题的(更)微不足道的提炼,以突出我的具体问题,而不是我的实际代码。
我们的目标是创建一个函数,该函数可以构建多个包含对通用类型共享数据的引用的向量。在以下示例的命名法中,我希望能够返回可以存储Struct1 和Struct2 的向量集合(由特征Trait 抽象),但是因为(在我的真实代码中) ) Struct1 和Struct2 比较大,会比较频繁地存放在比较多的地方,我宁愿存放对共享数据的引用,而不是到处复制。
我目前面临的问题(并且有很多中间版本)是:
- 由于我要存储的数据类型是
Trait,而不是Sized,我需要将引用存储在我的向量中 - 由于每个结构都将被多个向量引用,因此需要
&引用 - 从哲学上讲,给定结构没有单一的“所有者”,因此没有“正确”的位置来粘贴我的结构,因此它们不会超出
build_vectors函数的范围。- 我考虑尝试通过
Traits的全局向量来解决这个问题,我可以在其中指向引用,不幸的是,上面的问题 (1) 似乎排除了该策略。
- 我考虑尝试通过
.
struct Struct1;
struct Struct2;
trait Trait { fn name(&self) -> &str; }
impl Trait for Struct1 { fn name(&self) -> &str { "Struct1" } }
impl Trait for Struct2 { fn name(&self) -> &str { "Struct2" } }
fn shallow_copy<'a>(v: &'a Vec<&'a Box<Trait>>) -> Vec<&'a Box<Trait>> {
v.iter().map(|x|*x).collect()
}
fn build_vectors<'a>() -> (Vec<&'a Box<Trait>>, Vec<&'a Box<Trait>>) {
let box_struct1: &Box<Trait> = &(Box::new(Struct1) as Box<Trait>);
let box_struct2: &Box<Trait> = &(Box::new(Struct2) as Box<Trait>);
let vec1: Vec<&Box<Trait>> = vec![box_struct1];
let mut vec2: Vec<&Box<Trait>> = shallow_copy(&vec1);
vec2.push(box_struct2);
(vec1, vec2)
}
fn join_names(v: &Vec<&Box<Trait>>) -> String {
v.iter().map(|s| s.name()).collect::<Vec<_>>().connect(" ")
}
fn main() {
let (vec1, vec2) = build_vectors();
println!("vec1: {}", join_names(&vec1));
println!("vec2: {}", join_names(&vec2));
}
想要的输出是:
vec1: Struct1
vec2: Struct1 Struct2
【问题讨论】:
标签: rust