生存期问题:“类型具有不同的生存期,但是来自“自身”的数据会流入...”

时间:2019-03-10 14:23:01

标签: rust lifetime

我有此代码:

#[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

我已经意识到解决这个终身问题已经有好几个小时了,我不知道这是怎么回事。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

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

编辑:据我了解,您可能不知道的一件事是您正在创建一个trait对象,即启用动态调度的对象。如果不需要,可以将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的某个静态已知类型,该类型启用了静态编译时间分配。