Проблема времени жизни: «типы имеют разные времена жизни, но данные из« я »перетекают в ...» - PullRequest
0 голосов
/ 10 марта 2019

У меня есть этот код:

#[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 голосов
/ 10 марта 2019

Время жизни ссылки внутри 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, который включает статические, время компиляции.

...