rust - 终身问题 : "types have different lifetimes, but data from ' self' flows into. .."

标签 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

现在我已经与这个终生难题作斗争好几个小时了,但我不明白这是怎么回事;我做错了什么?

最佳答案

必须将 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/

相关文章:

rust - 为什么对 usize 数字的减号操作不能为负数,以及 Rust 惯用的处理方法是什么?

rust - 如何将 Box<T> 转换为 &T?

functional-programming - 如何创建没有样板代码的只读结构?

rust - 如何延长 Rust 中迭代器适配器内临时变量的生命周期?

generics - Rust说,即使设置了适当的生命周期,功能参数的生命周期也不够

rust - 我如何获得一个值的所有权,将引用传递给外部 API?

datetime - BadFormat 在使用 Chrono 时将字符串解析为最新

task - 将 Vec<Struct> 传递到新任务中

c++ - C++中类的静态数据成员和静态方法是静态对象吗?

rust - 如何解决此代码中的生命周期问题?