gpt4 book ai didi

rust - 构造 Rust 特征的惯用方法

转载 作者:行者123 更新时间:2023-12-03 11:40:18 25 4
gpt4 key购买 nike

在“The Ray Tracer Challenge”之后,我一直在用 Rust 编写 Ray Caster,并且我一直很难找出在 Rust 中实现多态性的正确方法。我的优先事项是该对象可以在多线程程序中使用,这似乎是主要问题。

我有两个案例,但我会专注于一个:形状。有不同种类的形状(坚持 able 后缀,我最初将我的特征称为 Intersectable )。这是一个有效的特征对象实现,但它不适用于多线程:

#[derive(Debug)]
pub struct Shape {
pub parent: Option<Arc<Shape>>,
pub transform: Matrix4,
pub material: Material,
pub intersectable: Box<Intersectable>,
}
pub trait Intersectable: Debug + IntersectableClone {
fn local_intersect(&self, ray: &Ray, object: Arc<Shape>) -> Vec<Intersection>;
}

pub trait IntersectableClone {
fn clone_box(&self) -> Box<Intersectable>;
}

impl<T> IntersectableClone for T
where
T: 'static + Intersectable + Clone,
{
fn clone_box(&self) -> Box<Intersectable> {
Box::new(self.clone())
}
}

impl Clone for Box<Intersectable> {
fn clone(&self) -> Box<Intersectable> {
self.clone_box()
}
}

#[derive(Clone, Debug)]
pub struct Sphere {}

impl Intersectable for Sphere {
fn local_intersect(&self, ray: &Ray, object: Arc<Shape>) -> Vec<Intersection> {
...sphere specific code
}
}

#[derive(Clone, Debug)]
pub struct Plane {}

impl Intersectable for Plane {
fn local_intersect(&self, ray: &Ray, object: Arc<Shape>) -> Vec<Intersection> {
...plane specific code
}
}


作为一个没有官方多态性的纯结构,我编写了一种静态调度,如下所示:
#[derive(Debug, Clone)]
pub enum IntersectableType {
Sphere,
Plane,
}

#[derive(Debug, Clone)]
pub struct Intersectable {
intersectable_type: IntersectableType,
}

impl Intersectable {
pub fn local_intersect(&self, ray: &Ray, object: Arc<Shape>) -> Vec<Intersection> {
match self.intersectable_type {
IntersectableType::Sphere => self.local_intersect_sphere(ray, object),
IntersectableType::Plane => self.local_intersect_plane(ray, object),
_ => Vec::new(),
}
}

fn local_intersect_sphere(&self, ray: &Ray, object: Arc<Shape>) -> Vec<Intersection> {
...sphere specific code
}

fn local_intersect_plane(&self, ray: &Ray, object: Arc<Shape>) -> Vec<Intersection> {
...plane specific implementation
}
}

这很好用,但感觉非常不使用rust 。我在使用其他实现时遇到了一些问题:
- 使用 Box<Intersectable> (当它是一个 Trait,而不是一个结构时),很难克隆(我复制了 How to clone a struct storing a boxed trait object?,但不喜欢使用 'static,因为这使得并发不可能)。
- 使用 Arc<Intersectable>似乎和 Box 有同样的问题,尽管也许有一种方法可以使它起作用。

有没有办法在 Rust 中做到这一点,允许我利用并发性而不是像这样编写手动静态调度?

最佳答案

我也在做“光线追踪器挑战”,虽然比你落后一点。我没有并发的想法。我现在尝试遵循 A-Frame ECS 的想法:

pub trait Primitive {}

pub struct Shape<T: Primitive> {
pub transformation: M4x4,
pub material: Material,
pub primitive: T,
}

pub struct Sphere;
impl Primitive for Sphere {}

关于rust - 构造 Rust 特征的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55072976/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com