Declaring a vector of feature objects with the lifetime parameter

I have a parameter Widgetparameterized by context type:

trait Widget<C> {
    fn f<'a>(&self, ctx: &'a mut C);
}

Some widgets whose context types are the same but contain links; therefore, they are parameterized:

struct Ctxt<'c> {
    data: &'c u32,
}

struct W1 {}
struct W2 {}

impl<'c> Widget<Ctxt<'c>> for W1 { // and W2
    fn f<'a>(&self, ctx: &'a mut Ctxt<'c>) {
        unimplemented!()
    }
}

I have a multivibra that wants to save several of them:

struct WV {
    widgets: Vec<Box<Widget<Ctxt<????>>>>,
}

impl<'c> Widget<Ctxt<'c>> for WV {
    fn f<'a>(&self, ctx: &'a mut Ctxt<'c>) {
        for w in &self.widgets {
            w.f(ctx);
        }
    }
}

I seem to need it Vec<Box<Widget<for<'c> Ctxt<'c>>>>; but you cannot do it! Alternatively, indicating only the lifetime in the definition f:

impl Widget<Ctxt> for W {
    fn f<'a, 'c>(&self, ctx: &'a mut Ctxt<'c>) {
        unimplemented!()
    }
}

This also does not work (there is no lifetime parameter for Ctxt).

The purpose of the context is to convey a volatile reference to something durable that is only necessary at the time f; The link &mutcannot be saved to W1, etc. I really do not want to indicate a lifetime for Ctxt.

, , ?

+4
1

, , . Ctxt, CtxtWidget impl<'c> Widget<Ctxt<'c>> :

trait Widget<C> {
    fn f<'a>(&self, ctx: &'a mut C);
}

struct W1 {}
struct W2 {}
struct Ctxt<'c> {
    data: &'c u32,
}

trait CtxtWidget {
    fn ctxt_f<'a, 'c>(&self, ctx: &'a mut Ctxt<'c>);
}

impl CtxtWidget for W1 {
    fn ctxt_f<'a, 'c>(&self, ctx: &'a mut Ctxt<'c>) {
        unimplemented!()
    }
}
impl CtxtWidget for W2 {
    fn ctxt_f<'a, 'c>(&self, ctx: &'a mut Ctxt<'c>) {
        unimplemented!()
    }
}

impl<'c> Widget<Ctxt<'c>> for Box<CtxtWidget> {
    fn f<'a>(&self, ctx: &'a mut Ctxt<'c>) {
        self.ctxt_f(ctx);
    }
}

struct WV {
    pub widgets: Vec<Box<CtxtWidget>>,
}

fn main() {
    let mut wv = WV{widgets: Vec::new()};
    wv.widgets.push(Box::new(W1{}));
    wv.widgets.push(Box::new(W2{}));
    let u = 65u32;
    let mut ctxt = Ctxt{data: &u};
    for widget in &wv.widgets {
        widget.f(&mut ctxt);
    }
}

( )

CtxtWidget for<'c> Widget<Ctxt<'c>>.

( , ).

+3

Source: https://habr.com/ru/post/1654185/


All Articles