如何在不在API中公开Rc的情况下共享资源



我正在处理一个几何机箱,我想为了让事情顺利进行,我应该在引用共享点时使用Rc。例如:

struct Point {
point: Vec4,
}
struct Line {
points: [Rc<Point>; 2],
}
struct Tri {
points: [Weak<Point>; 3],
edges: [Rc<Line>; 3],
}
struct Tetra {
points: [Weak<Point>; 4],
edges: [Weak<Line>; 6],
faces: [Rc<Tri>; 4],
}

这是有道理的,因为它似乎是跟踪单纯形的组成部分的最有效的方法。问题出在API中。我不想公开这个Rc内部,如果我可以直接传入引用,我会喜欢它

let points = [Point::new(p0), Point::new(p1), Point::new(p2), Point::new(p3)];
let tris = [
Tri::new(&points[0], &points[1], &points[2]),
Tri::new(&points[2], &points[3], &points[0])
];

等等。而不需要用户自己明确地处理CCD_ 3。

我们通常在这里看到什么样的模式?

如果您希望在不由用户自己管理Rc的情况下共享资源,则可以正常创建内部结构,并为公共接口创建Rc周围的包装器。

保持你的结构原样,但最好使用一个命名方案来指示它们是内部的(通常是InnerImpl后缀(:

struct PointInner {
point: Vec4,
}
struct LineInner {
points: [Rc<PointInner>; 2],
}
struct TriInner {
points: [Weak<PointInner>; 3],
edges: [Rc<LineInner>; 3],
}
struct TetraInner {
points: [Weak<PointInner>; 4],
edges: [Weak<LineInner>; 6],
faces: [Rc<TriInner>; 4],
}

然后创建面向用户的类型,这些类型只是Rc的包装器,具有处理内部链接的良好外观(您可以像我所做的那样使用inner字段,也可以使用新的类型结构(:

pub struct Point {
inner: Rc<PointInner>,
}
pub struct Line {
inner: Rc<LineInner>,
}
pub struct Tri {
inner: Rc<TriInner>,
}
pub struct Tetra {
inner: Rc<TetraInner>,
}
impl Point {
pub fn new(point: Vec4) -> Point {
Point {
inner: Rc::new(PointInner { point }),
}
}
}
impl Tri {
pub fn new(p1: &Point, p2: &Point, p3: &Point) -> Tri {
Tri {
inner: Rc::new(TriInner {
points: [
Rc::downgrade(&p1.inner),
Rc::downgrade(&p2.inner),
Rc::downgrade(&p3.inner),
],
edges: [
Rc::new(LineInner {
points: [Rc::clone(&p1.inner), Rc::clone(&p2.inner)],
}),
Rc::new(LineInner {
points: [Rc::clone(&p2.inner), Rc::clone(&p3.inner)],
}),
Rc::new(LineInner {
points: [Rc::clone(&p3.inner), Rc::clone(&p1.inner)],
}),
],
}),
}
}
}

有了它,您所需的代码就可以毫无更改地工作。看到它在操场上工作。

相关内容

最新更新