0

I can't figure out the lifetime parameters for this code. Everything I try usually results in a compiler error:

consider using an explicit lifetime parameter as shown

or something like

in type &'ent Entity<'a, 'ent>, reference has a longer lifetime than the data it references.

Entity, Reference are simplified versions to keep this example minimal.

struct Entity<'a> {
    id: i32,
    name: &'a str,
    references: Option<Vec<Reference<'a>>>,
}

struct Reference<'a> {
    entity: &'a Entity<'a>,
}

fn main() {
    let mut ents: Vec<Entity> = vec![Entity {
                                      id: 0,
                                      name: "Zero",
                                      references: None,
                                  },
                                  Entity {
                                      id: 1,
                                      name: "One",
                                      references: None,
                                  },
                                  Entity {
                                      id: 2,
                                      name: "Two",
                                      references: None,
                                  },
                                  Entity {
                                      id: 3,
                                      name: "Three",
                                      references: None,
                                  }];
    let references_ents_id = vec![vec![3, 1, 2], vec![1], vec![0, 3], vec![3, 0]];
    create_references(&references_ents_id, &mut ents);
}

fn create_references(refs_id: &Vec<Vec<i32>>, ents_vec: &mut Vec<Entity>) {
    for (id_ent, references) in refs_id.iter().enumerate() {
        let mut references_of_ent: Vec<Reference> = vec![];
        for id_ent in references {
            references_of_ent.push(Reference {
                entity: ents_vec.iter().find(|ent| ent.id == *id_ent).unwrap(),
            });
        }
        ents_vec[id_ent].references = Some(references_of_ent);
    }
}

Rust Playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
saruman9
  • 33
  • 3

1 Answers1

0

I was looking in the wrong direction. And so, I found a solution, but unfortunately it is not safe.

  • You can implement it using Rc and Weak to allow shared ownership of nodes, although this approach pays the cost of memory management.
  • You can implement it using unsafe code using raw pointers. This will be more efficient, but bypasses Rust’s safety guarantees.
  • Using borrowed references with UnsafeCell.

Rust FAQ

Other answer on SO

Example of implementation unsafe version with raw pointers:

struct Entity<'a> {
    id: i32,
    name: &'a str,
    references: Option<Vec<Reference<'a>>>,
}

struct Reference<'a> {
    entity: *const Entity<'a>,
}

Rust Playground: https://play.rust-lang.org/?gist=8237d8cb80a681c981a85610104f2e5c&version=stable&backtrace=0

saruman9
  • 33
  • 3