Rust 构造锈菌特征的惯用方法
在“光线跟踪器挑战”之后,我一直在写一本《锈》中的光线投射器,我一直很难找到在锈中实现多态性的正确方法。我优先考虑的是对象可以在多线程程序中使用,这似乎是主要问题 我有两个例子,但我会集中在一个:一个形状。有不同类型的形状(使用我最初称为我的traitRust 构造锈菌特征的惯用方法,rust,Rust,在“光线跟踪器挑战”之后,我一直在写一本《锈》中的光线投射器,我一直很难找到在锈中实现多态性的正确方法。我优先考虑的是对象可以在多线程程序中使用,这似乎是主要问题 我有两个例子,但我会集中在一个:一个形状。有不同类型的形状(使用我最初称为我的traitIntersectable的后缀)。这是一个有效的trait对象实现,但它不适用于多线程: #[derive(Debug)] pub struct Shape { pub parent: Option<Arc<Shape>
Intersectable
的后缀)。这是一个有效的trait对象实现,但它不适用于多线程:
#[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
}
}
#[派生(调试)]
酒吧结构形状{
pub parent:Option,但不喜欢使用“static”,因为这使得并发不可能实现)。
-使用Arc
似乎与Box
有着相同的问题,尽管也许有一种方法可以让它起作用
有没有一种方法可以在Rust中实现这一点,从而允许我利用并发性,而不是像这样编写手动静态调度?我也在研究“光线跟踪器挑战”,虽然比您落后一点。我没有考虑并发性。我现在尝试遵循以下想法:
pub-trait基元{}
酒吧结构形状{
pub转换:M4x4,
酒吧材料:材料,
酒吧原语:T,
}
pub结构球;
球体{}的impl基元
我也在研究“光线跟踪器挑战”,虽然比你落后了一点。我没有考虑到并发性。我现在尝试遵循以下想法:
pub-trait基元{}
酒吧结构形状{
pub转换:M4x4,
酒吧材料:材料,
酒吧原语:T,
}
pub结构球;
球体{}的impl基元
您能否展示您迄今为止尝试过的trait方法的功能示例,以便我们了解您遇到的问题?这比我们从头开始要容易得多。是的,我已经添加了之前的主要实现!也许您可以只存储一个函数指针fn(&Ray,Arc)->Vec
在你的形状中。我相信fn
是Clone+Send
。这基本上就是你在空结构上使用动态调度所做的。这是一个我没有想到的非常有趣的概念,我会尝试一下并报告回来!哈,我现在也在那里!但有点不那么先进。如何将从我的领域中扮演一个角色。你能展示你迄今为止尝试过的特质方法的功能示例吗,这样我们就可以理解你的问题了?这比我们从头开始要容易得多。是的,我已经添加了我之前的主实现!也许你可以只存储一个函数指针fn(&Ray,Arc)->Vec
在你的形状中。我相信fn
是Clone+Send
。这基本上就是你在空结构上使用动态调度所做的。这是一个我没有想到的非常有趣的概念,我会尝试一下并报告回来!哈,我现在也在那里!但有点不那么先进。如何将在我的球体上做一个形状。
#[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
}
}