Structure with a field whose lifetime depends on a second field


#1

This is basically the code I would like to implement:

use std::boxed::Box;

struct X<'a> {
    data: &'a String
}

struct Y {
    data: String
}

impl Y {
    fn create<'a>(&'a self) -> X<'a> {
        X { data: &self.data }
    }
}

struct Z<'a> {
    y: Box<Y>,
    x: X<'a>
}

impl<'a> Z<'a> {
    fn new(y: Box<Y>) -> Z<'a> {
        let x = y.create();

        Z { y: y, x: x }
    }
    
    fn destroy(self) -> Box<Y>
    {
        self.y
    }
}

fn main() {
    let y = Box::new(Y { data: "foo".to_string() });
    let z = Z::new(y);
}

Structures X and Y come from a 3rd party library so I cannot change them. I would like to create structure Z. Putting Y in a box is not required, I just through I might be able to get away with more if it was.

What I’d really like to do is implement Drop for Z so that Y is passed back to a collection of Ys. So I think i’m going to actually have to use Box::into_raw and Box::from_raw so that the destruction of Z doesn’t destroy Y.

However I still have the problem of the lifetime on Z, since X needs a lifetime, Z needs a lifetime, but I don’t know how to set Z’s lifetime.


#2

If Z wants to borrow something from Y I don’t think it makes sense to also own Y. It could borrow Y though:

struct Z<'a> {
    y: &'a Y,
    x: X<'a>,
}

impl<'a> Z<'a> {
    fn new(y: &Y) -> Z {
        let x = y.create();
        Z { y: y, x: x }
    }
}

#3

There’s a gazillion posts on stackoverflow. The main one is http://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct?rq=1 I think.


#4

I guess I’m going to have to restructure how this code is written. Really I want an instance of X in a thread local variable, since it’s needed in a bunch of locations that are far apart in the call stack, but I may just have to keep passing it down the stack. :unamused: