Rust 在结构初始值设定项中使用对新结构的引用
我试图在Rust中创建一个不相交的集合结构。看起来像这样Rust 在结构初始值设定项中使用对新结构的引用,rust,Rust,我试图在Rust中创建一个不相交的集合结构。看起来像这样 struct DisjointSet<'s> { id: usize, parent: &'s mut DisjointSet<'s>, } 其中,self是对将要创建的对象的引用 我尝试通过创建自定义构造函数来解决这个问题。但是,我的尝试失败,因为不允许部分初始化。编译器建议使用Option,正如@delnan所说的,这些类型的数据结构的核心是有向无环图(dag),包括所有需要的共享。R
struct DisjointSet<'s> {
id: usize,
parent: &'s mut DisjointSet<'s>,
}
其中,self
是对将要创建的对象的引用
我尝试通过创建自定义构造函数来解决这个问题。但是,我的尝试失败,因为不允许部分初始化。编译器建议使用
Option,正如@delnan所说的,这些类型的数据结构的核心是有向无环图(dag),包括所有需要的共享。Rust严格限制共享可能发生的情况,因此在这种情况下,要说服编译器接受您的代码需要付出一些额外的努力
幸运的是,“所有需要的共享”并不是字面上的“所有共享”:DAG是非循环的(模想要有parent:self
),所以像Rc
或Arc
这样的引用计数类型是处理共享的完美方式(如果有循环,引用计数就不那么好)。具体而言:
struct DisjointSet {
id: Cell<usize>,
parent: Rc<DisjointSet>,
}
(选项
是免费的:选项
是一个可为空的指针,就像Rc
是一个不可为空的指针一样,人们可能需要一个关于“我是否有父项”的分支。)
如果您打算采用这种方法,我建议不要尝试使用选项进行部分初始化,而是使用它来表示给定集合是“根”的事实。使用此表示法很容易向上遍历链,例如
fn find_root(mut x: &DisjointSet) -> &DisjointSet {
while let Some(ref parent) = x.parent {
x = parent
}
x
}
同样的方法也适用于引用,但生命周期通常很难处理。您是否尝试过创建一个新的函数来构造一个实例,然后在返回前对其进行修补?可能重复的&mut
对于父引用无论如何都不起作用,因为它不允许别名<代码>&
允许这样做,但仍然需要一些练习(如果您想在构建后更改id
,还需要一个单元格
)。它还对所有DisjointSet
s(不能有Vec)的集合提出了奇怪的要求
struct DisjointSet {
id: Cell<usize>,
parent: Option<Rc<DisjointSet>>,
}
fn find_root(mut x: &DisjointSet) -> &DisjointSet {
while let Some(ref parent) = x.parent {
x = parent
}
x
}