gpt4 book ai didi

generics - 使用泛型参数对特征进行 Rust 动态调度

转载 作者:行者123 更新时间:2023-12-03 11:43:15 26 4
gpt4 key购买 nike

我有以下
Rust Playground permalink

来自我的关注 Ray Tracing in a Weekend .

在实现 Material 时,我选择创建一个特征 Material .

我的想法是世界上的物体会有 material属性和光线 Hit Hit可以查看对象并按需索要 Material 。这适用于我的 Normal遵循类似想法的特质。我用动态调度实现了这一切,尽管我认为我已经掌握了足够的能力,也可以通过 trait bound 静态地完成它。

在链接的代码中,您会看到第 13 行,我要求那些实现 Normal有一个方法会返回 Material .这表明现在 Normal不再有资格成为特征对象 error[E0038]: the trait正常 cannot be made into an object
如果我从 this 等问题中正确理解似乎由于泛型是单态化的,Rust 运行时不可能泄露material 的适当方法。鉴于实现 Normal 的每种类型表面上可能有一个不同的类型?这对我来说并不完全正确,因为看起来,放在与 Rust 运行时相同的位置,我将能够查看 Normal我手头的实现者,比如说Sphere并说我会查看Sphere的虚表。你能解释一下我在哪里错了吗?

从那里开始,我尝试简单地与编译器抗争并进行静态调度。
第 17-21 行

struct Hit<'a> {
point: Vec3,
distance: f32,
object: &'a dyn Normal,
}

变成了
struct Hit<'a, T: Normal> {
point: Vec3,
distance: f32,
object: &'a T,
}

从那里开始,我不得不尝试一个接一个地堵住一个又一个洞,似乎看不到尽头。

除了了解我目前的理解存在根本性错误之外,我还可以做哪些不同的设计选择?

最佳答案

我可能遗漏了一些东西,但我认为你可以——至少从我所看到的情况来看——进一步走你的路。

我认为您可以更改此功能:

fn material<T: Material>(&self) -> T;

就目前而言,它说:任何 Normal提供功能 material调用者可以在其中指定 Material该函数将返回。

但是(我认为)您要声明的是:任何 Normal有一个可以由调用者请求的 Material 。但是来电者无权口述任何 Material那将被退回。要将其转换为代码,您可以声明:
fn material(&self) -> &dyn Material;

这表明 material返回 Material (作为特征对象)。

然后, Sphere可以实现 Normal :
impl<'a> Normal for Sphere<'a> {
fn normal(&self, point: &Vec3) -> Ray {
Ray::new(point, &(point - &self.center))
}
fn material(&self) -> &dyn Material {
self.material
}
}

Link to playground.

关于generics - 使用泛型参数对特征进行 Rust 动态调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61420414/

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