我有这个代码:
#[derive(Clone, Copy)]
pub struct HitRecord<'a> {
pub t: f32,
pub p: Vector3<f32>,
pub normal: Vector3<f32>,
pub material: Option<&'a Material>,
}
pub struct Sphere<T>
where
T: Material,
{
pub center: Vector3<f32>,
pub radius: f32,
pub material: T,
}
impl<T> Sphere<T> {
fn hit<'a, 'b>(&'a self, ray: &Ray, t_min: f32, t_max: f32, record: &'b mut HitRecord) -> bool
where
'a: 'b,
{
record.material = Some(&self.material);
}
}
我明白record
的生命周期肯定比self
短,所以我给它们分配了不同的生命周期,并设置'a
来包围'b
。但我仍然得到这个:
error[E0623]: lifetime mismatch
--> src\tracer\sphere.rs:54:35
|
30 | fn hit<'a, 'b>(&'a self, ray:&Ray, t_min:f32, t_max:f32, record:&'b mut HitRecord) -> bool where 'a: 'b {
| -------- ---------
| |
| these two types are declared with different lifetimes...
...
54 | record.material = Some(&self.material);
| ^^^^^^^^^^^^^^^^^^^^ ...but data from `self` flows into `record` here
现在我已经与这个终生难题作斗争好几个小时了,但我不明白这是怎么回事;我做错了什么?
最佳答案
必须将 HitRecord
中引用的生命周期设置为与 &self 的生命周期相同(或更短),以便从 record
到 self 的引用是正确的.您甚至不必显式设置 'a 和 'b 之间的关系,因为重要的不是 record
本身的生命周期,而是结构成员 material
的生命周期.这个签名应该有效:
fn hit<'a>(&'a self, ray:&Ray, t_min:f32, t_max:f32, record:&mut HitRecord<'a>) -> bool
编辑:我看到您可能没有意识到的一件事是您正在创建特征对象,即启用动态调度的对象。如果不需要,您可能需要将 HitRecord
的声明更改为
#[derive(Clone, Copy)]
pub struct HitRecord<'a, T: Material> {
pub t: f32,
pub p: Vector3<f32>,
pub normal: Vector3<f32>,
pub material: Option<&'a T>
}
通过这种方式,您可以将结构固定为某个实现Material
的静态已知类型,从而启用静态编译时分派(dispatch)。
关于rust - 终身问题 : "types have different lifetimes, but data from ' self' flows into. ..",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55088647/