终身问题:“类型有不同的生命周期,但来自'自我'的数据流入......”

问题描述 投票:0回答:1

我有这个代码:

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

我现在已经花了几个小时来解决这个终生难题,我不明白这里发生了什么。我究竟做错了什么?

rust lifetime
1个回答
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

编辑:我看到你可能没有意识到的一件事是你正在创建一个特征对象,即启用动态调度的东西。如果您不需要,可能需要将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的某个静态已知类型,该类型启用静态编译时调度。

© www.soinside.com 2019 - 2024. All rights reserved.