我有这个代码:
#[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
的某个静态已知类型,该类型启用静态编译时调度。