如何从采用 &self 的方法克隆 Rc

问题描述 投票:0回答:1

我有一个结构体

Region
,其中包含
[Option<Rc<RefCell<Region>>>; 2]
作为其
subregions
Option<Weak<RefCell<Region>>>
作为其
container
。我正在编写一种在
Region
self
之间插入新的
self.container
的方法,这需要我将 Rc 克隆到
self
以将其包含在新创建的
Region
中作为其
subregions
之一。当
self.container
Some
时,这是可能的,因为我可以走到容器处,然后克隆其与
subregion
匹配的
self
,但是当
self
None
作为其容器时,我不知道如何从传递到方法中的
Rc
获取
self
&mut self
的克隆。

这里有一些代码可以让它更清楚。

struct Region {
    subregions: [Option<Rc<RefCell<Region>>>; 2],
    container: Option<Weak<RefCell<Region>>>,
}

impl Region {
    fn clone_from_container(&self) -> Option<Rc<RefCell<Region>>> {
        Some(Rc::clone(&self.container
                       .as_ref()?
                       .upgrade()
                       .unwrap()
                       .borrow()
                       .subregions[self.from()]
                       .as_ref()
                       .unwrap()))
    }

    pub fn insert_above(&mut self) -> Rc<RefCell<Region>> {
        let new = Rc::new(RefCell::new(Region {
            subregion: [self.clone_from_container(),None],
            container: self.container.clone(),
        }));
        self.replace(new.clone());
        self.container = Some(Rc::downgrade(&new.clone()));
        new
    }
}

在我的实际代码中还有更多函数,但这些只是长方法链的别名,用于拆箱

Rc
RefCell
以便让我实际获取数据。我尽力只保留重要的细节。

我排除的方法,

Region::replace
Region::from
非常简单,它们的实现并不重要。
replace
走到
container
并用新区域替换对
self
的引用(与
clone_from_container
非常相似,但改变了
Region
),并且
from
只是找到
Region的索引
在其
container
subregions
内(0 或 1)

在设置

subregion
new
时,我希望能够说出类似
self.clone_from_container().or(Rc::clone(self))
的内容,但显然鉴于
self
传递的类型,这是不可能的。

我认为可能需要让它成为一个静态工厂函数,而不是一个实例方法,所以我们可以使用

self
类型传递
Rc<RefCell<Region>>
,但我也认为可以使用
Rc::new_cyclic
;然而,这个功能有点令人困惑,我不太确定如何使用它。

rust self reference-counting cyclic-reference refcell
1个回答
0
投票

为了简单起见,我会说

Rc<Region>
而不是
Rc<RefCell<Region>>

如果我理解正确的话,这就是你的情况:

let region = Region::new()
let rc = Rc::new(region)

你有一个方法,例如:

impl Region {
    fn my_function(&mut self) {
        // Here you want to somehow get a reference to `rc` (the Rc that contains this region)
    }
}

这是不可能的,因为

Region
不知道它在
Rc
内。你必须以某种方式告诉它它在 Rc 内。

一种可能的解决方案是不使用

self
。例如:

impl Region {
    fn my_function(value: Rc<Self>) {
        // Now you have access to `rc`
    }
}

另一个选择,正如 PitaJ 所建议的,是为

Rc<Region>
创建一个特征,在这种情况下,
self
将是
Rc<Region>
,这样你就可以访问
rc

© www.soinside.com 2019 - 2024. All rights reserved.