rust - 共享弱特征对象引用
问题描述
我试图提供非拥有结构的“视图”来分离系统的组件。
假设一组具有不同方法的特征:Drawable
,Modifiable
以及许多实现至少一个特征的结构 - SimpleBox
,Panel
,Expression
。
系统的不同组件将需要使用特定特征的方法频繁访问这些对象的序列;考虑 aDrawingManager
或 a 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
为它制作的所有内容的列表。
当我们想要删除一个对象时,我们将它从相应的列表中删除,并删除 hashmap 中的条目,使所有Weak
引用无效。
但是,实现这一点失败了,因为要插入HashMap
,必须向上转换Rc<Trait>
-> Rc<Any>
,然后才能向下转换它。
解决方案
我不确定这是否是这样做的惯用方式,但我已经开发了一个提供此功能的板条箱 - dependent_view
.
使用板条箱,最初的问题可以通过使用DependentRc
而不是普通Rc
的来解决:
struct ObjectManager {
boxes: Vec<DependentRc<Box>>,
panels: Vec<DependentRc<Panel>>,
expressions: Vec<DependentRc<Expression>>
}
let object_manager : ObjectManager = ObjectManager::new();
然后使用 crate 提供的宏,我们可以获得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<>
对它的引用都无效。
推荐阅读
- pytorch - 如何用 2D 掩码掩盖 3D 张量并保持原始向量的尺寸?
- python - 为什么不保留 .capitalize() 方法,但如果我这样做 .sort() 是?我该如何保留它?
- javascript - jQuery Datables:选择时更新同一行上的按钮类和文本
- python - 从 dict 合并多个数据帧
- c - 制表符分隔的文本到 C 中的 CSV
- c++ - 你能用 perf 分析一个函数的单个调用吗?
- java - RETROFIT2 无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例
- c# - 将 H264 帧解码为位图
- blazor - 如何使用 https 和自定义域在本地运行 Blazor WebAssembly?
- android - Spinner:使用点击监听器以编程方式选择项目