< 返回版块

wmlgl 发表于 2021-04-04 22:26

Tags:生命周期

为什么owner.do_something_def_litftime_b()没问题,owner.do_something_def_litftime_a()会出错呢?

struct ThirdPartPage<'a> {
    name: &'a str,
    content: &'a str
}

struct ThirdPartDoc<'a> {
    page: ThirdPartPage<'a>
}

impl <'a> ThirdPartDoc<'a> {
    fn get_page(&self) -> &ThirdPartPage<'a> {
        &self.page
    }
}

///////// resource //////////


trait ResourceTrait<'a> {
    fn get_content(&self) -> &str;
}

struct TirdpartResource<'a> {
    data: &'a ThirdPartPage<'a>
}

impl<'a> ResourceTrait<'a> for TirdpartResource<'a> {
    fn get_content(&self) -> &str {
        self.data.content
    }
}

////////// main logic ////////
struct Owner<'a> {
    doc: Option<ThirdPartDoc<'a>>
}

trait OwnerTrait<'a> {
    fn get_resource(&'a self) -> Option<Box<dyn ResourceTrait<'a> + 'a>>;
    fn do_something(&self);
    fn do_something_def_litftime_a(&'a self);
    fn do_something_def_litftime_b<'b>(&'b self);
}

impl<'a> OwnerTrait<'a> for Owner<'a> {
    fn get_resource(&'a self) -> Option<Box<dyn ResourceTrait<'a> + 'a>> {
        match &self.doc {
            Some(doc) => {
                Some(Box::new(TirdpartResource {
                    data: doc.get_page()
                }))
            },
            None => Option::None
        }
    }
    fn do_something(&self) { }
    fn do_something_def_litftime_a(&'a self) { }
    fn do_something_def_litftime_b<'b>(&'b self) { }
}

fn new_owner<'a>(otype: i64) -> Result<Box<dyn OwnerTrait<'a> + 'a>, String> {
    let owner = Owner {
        doc: Some(ThirdPartDoc {
            page: ThirdPartPage {
                name: "page",
                content: "content"
            }
        })
    };
    Ok(Box::new(owner))
}

fn main() {
    let owner = Owner {
        doc: Some(ThirdPartDoc {
            page: ThirdPartPage {
                name: "page",
                content: "content"
            }
        })
    };
    let mut owner: Box<dyn OwnerTrait> = Box::new(owner);
    // let mut owner = new_owner(0).unwrap();
    
    owner.do_something();
    owner.do_something();
    owner.do_something_def_litftime_b();
    owner.do_something_def_litftime_a();
    
    let res = owner.get_resource();
    
    println!("{}", res.unwrap().get_content());
}

这里是错误提示


error[E0597]: `*owner` does not live long enough
  --> src/main.rs:89:5
   |
89 |     owner.do_something_def_litftime_a();
   |     ^^^^^ borrowed value does not live long enough
...
94 | }
   | -
   | |
   | `*owner` dropped here while still borrowed
   | borrow might be used here, when `owner` is dropped and runs the destructor for type `Box<dyn OwnerTrait<'_>>`

error: aborting due to previous error; 2 warnings emitted

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground`


评论区

写评论
Ammann 2021-04-26 11:44

1、Box<dyn T>Box<dyn T + 'static> 的简写

2、&'a self,因为 'a 是结构体对象的生命期参数,所以调用此方法告诉编译器要在 'a 期间(对象的生命期)都保持对 self 的借用。

3、由 1 知,*owner 的 'a 是 'static,所以调用 owner.do_something_def_litftime_a() owner.get_resource() 相当于宣布要在 static 生命期内保持对 *owner 的借用。

4、而 owner 在 main 结尾就销毁,与 3 矛盾,所以会报 “borrowed value does not live long enough”错

5、&'b self 中 'b 是方法本身的生命期参数,同时这个方法没有输出生命期, 意思是,调用这个方法只要在方法调用期间保持对 self 的借用。

6、由 5 可知 owner.do_something_def_litftime_b() 方法调用完对 self 的借用就结束了,所以没问题

7、 fn do_something(&self);fn do_something<'b>(&'b self) 的简写,所以 owner.do_something() 也没问题。

1 共 1 条评论, 1 页