Rust 在结构初始值设定项中使用对新结构的引用

Rust 在结构初始值设定项中使用对新结构的引用,rust,Rust,我试图在Rust中创建一个不相交的集合结构。看起来像这样 struct DisjointSet<'s> { id: usize, parent: &'s mut DisjointSet<'s>, } 其中,self是对将要创建的对象的引用 我尝试通过创建自定义构造函数来解决这个问题。但是,我的尝试失败,因为不允许部分初始化。编译器建议使用Option,正如@delnan所说的,这些类型的数据结构的核心是有向无环图(dag),包括所有需要的共享。R

我试图在Rust中创建一个不相交的集合结构。看起来像这样

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
}