Rust 生命周期 - lifetime in struct

出自: www.zhihu.com/column/rust-shen

上回书说到,生命周期在函数中的使用。现在我们看看结构中,为什么也要使用这玩意。

简单的说,假如我们的结构项中,需要引用某个外部的变量,我们必须保证被引用的变量生命周期要长于我们的结构。举例:

fn main() {
  let opt = Option::new(1, "hello");
  let svc = Service::new(&opt);
  println!("Hello, {}", svc.name());
}

这段代码,看上去毫无问题,svc要引用opt, 引用前,opt就存在了。生命周期长于svc 。

因此,在设计Service这个结构和实现时,要给自己和要引用的Option,都加上时间周期,保证它们二个的生命紧密相连。于是主耶稣,就是编译器,觉得这是好的,甚是欣慰。愉快的让你通过了编译。这是完整代码:

struct Option {
  pub some_int : i32,
  pub some_string : String
}

impl Option {
  pub fn new<T: Into<String>>(some_int : i32, some_string : T) -> Option {
    Option { some_int: some_int, some_string: some_string.into() }
  }
}

struct Service<'a> {
  option: &'a Option
}

impl<'a> Service<'a> {
  pub fn new(option: &'a Option) -> Service {
    Service { option: option }
  }

  pub fn name(&self) -> String {
    self.option.some_string.clone()
  }
}

生命周期说白了就是作用域的名字。每一个引用以及包含引用的数据结构,都要有一个生命周期来指定它保持有效的作用域。

写好了这个上述代码,某天,你或者你的小傻蛋伙伴,开始使用这个”类”了, 他写下了这段代码:


fn create_service() -> Service {  // compile error
  let opt = Option::new(1, "hello");
  Service::new(&opt);
}

编译没通过。原因是编译器发现,opt生命周期太短了,函数返回后,它就丢失了。而Service返回了一个不存在的指针。看,rust编译器这个伟大的上帝、法官。又防止了一个危险的错误。这就是Rust,把事情搞搞清楚,明确定义,以literal的形式约束。加上编译器无所不在的检查能力,就能写出让老板轻松、客户放心、程序猿操碎心的优质代码。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!