The compiler suggests I add a 'static lifetime because the parameter type may not live long enough, but I don't think that's what I want

前端 未结 2 671
[愿得一人]
[愿得一人] 2020-11-22 09:35

I\'m trying to implement something that looks like this minimal example:

trait Bar {}

struct Foo {
    data: Vec>         


        
2条回答
  •  死守一世寂寞
    2020-11-22 10:05

    Check out the entire error:

    error[E0310]: the parameter type `U` may not live long enough
     --> src/main.rs:9:24
      |
    8 |     fn add>(&mut self, x: U) {
      |            -- help: consider adding an explicit lifetime bound `U: 'static`...
    9 |         self.data.push(Box::new(x));
      |                        ^^^^^^^^^^^
      |
    note: ...so that the type `U` will meet its required lifetime bounds
     --> src/main.rs:9:24
      |
    9 |         self.data.push(Box::new(x));
      |                        ^^^^^^^^^^^
    

    Specifically, the compiler is letting you know that it's possible that some arbitrary type U might contain a reference, and that reference could then become invalid:

    impl<'a, T> Bar for &'a str {}
    
    fn main() {
        let mut foo = Foo { data: vec![] };
    
        {
            let s = "oh no".to_string();
            foo.add(s.as_ref());
        }
    }
    

    That would be Bad News.

    Whether you want a 'static lifetime or a parameterized lifetime is up to your needs. The 'static lifetime is easier to use, but has more restrictions. Because of this, it's the default when you declare a trait object in a struct or a type alias:

    struct Foo {
        data: Vec>>,
        // same as
        // data: Vec + 'static>>,
    } 
    

    However, when used as an argument, a trait object uses lifetime elision and gets a unique lifetime:

    fn foo(&self, x: Box>)
    // same as
    // fn foo<'a, 'b>(&'a self, x: Box + 'b>)
    

    These two things need to match up.

    struct Foo<'a, T> {
        data: Vec + 'a>>,
    }
    
    impl<'a, T> Foo<'a, T> {
        fn add(&mut self, x: U)
        where
            U: Bar + 'a,
        {
            self.data.push(Box::new(x));
        }
    }
    

    or

    struct Foo {
        data: Vec>>,
    }
    
    impl Foo {
        fn add(&mut self, x: U)
        where
            U: Bar + 'static,
        {
            self.data.push(Box::new(x));
        }
    }
    

提交回复
热议问题