共享弱特征对象引用

时间:2018-07-31 20:00:50

标签: rust traits trait-objects

我试图提供非所有结构的“视图”以分离系统的各个组成部分。

假设一组具有不同方法的特征:DrawableModifiable和实现至少一个特征的多个结构-SimpleBoxPanel,{ {1}}。

系统的不同组件将需要使用特定特征的方法频繁访问这些对象的序列;考虑使用ExpressionDrawingManager

ModifyManager

虽然两个管理器中都可以引用单个对象,但是请假定所有结构都有单独的单个所有者:

struct DrawingManager {
    items: Vec<Weak<Drawable>>,
}

struct ModifyManager {
    items: Vec<Weak<Modifiable>>
}

理想情况下,能够从一个位置管理删除结构将很有用,例如,简单地将其从struct ObjectManager { boxes: Vec<Rc<Box>>, panels: Vec<Rc<Panel>>, expressions: Vec<Rc<Expression>>, } 中删除就足以使所有其他组件中的引用无效(因此使用ObjectManager )。

  • 有没有办法做到这一点?
  • 这是实现此目标的正确方法吗?
  • 是否有更惯用的方式来实现此功能?

该系统包含多个特征,因此使用所有其他特征的方法制作一个特征似乎是个坏主意。多个特征具有不止一种方法,因此不可能用闭包替换它们。

我尝试过的事情

由于一个对象可能会产生一个或多个Weak,因此我们可以设想使用Rc<Trait>来实现该目标,从而使每个结构都具有唯一的HashMap<ID, Vec<Rc<Any>>>,该映射到所有列表ID就是为此而做的。

当我们要删除对象时,我们将其从相应的列表中删除,并删除哈希图中的条目,从而使所有Rc引用无效。

但是,实现这一点失败了,因为要插入Weak-> HashMap,必须插入Rc<Trait>-> Rc<Any>,然后再向下转换。

1 个答案:

答案 0 :(得分:0)

我不确定这是否是惯用的方式,但此后我开发了一个可提供此功能的板条箱-dependent_view

使用板条箱,可以通过使用DependentRc而不是普通的Rc来解决最初的问题:

struct ObjectManager {
    boxes: Vec<DependentRc<Box>>,
    panels: Vec<DependentRc<Panel>>,
    expressions: Vec<DependentRc<Expression>>
}

let object_manager : ObjectManager = ObjectManager::new();

然后使用板条箱提供的宏,我们可以获得对这些结构的Weak<>引用:

let box_view : Weak<Drawable> = to_view!(object_manager.boxes[0]);
let panel_view : Weak<Drawable> = to_view!(object_manager.panels[0]);
let expression_view : Weak<Drawable> = to_view!(object_manager.expressions[0]);

通过此操作,删除相应的DependentRc<>将使所有由其构成的Weak<>引用无效。