首页 文章

什么生锈的生命周期实际上意味着什么?

提问于
浏览
5

所以,在:

fn v1<'a> (a:~[&'a str]) -> ~[&'a str] {
  return a;
}

#[test]
fn test_can_create_struct() {
  let x = v1("Hello World".split(' ').collect());
}

我知道,我读过http://static.rust-lang.org/doc/master/guide-lifetimes.html#named-lifetimes,但我不明白这段代码到底是做什么的 .

该函数基本上是参数化的,如通用fn,但有一生,是我在IRC Channels 上看到的,但让我们想象就是这样,我们有一个L,这是一些特定的生命周期结构 .

显然我隐含地称:

v1::<L>("Hello World".split(' ').collect());

..但我不是 . 传递给这个函数的生命周期是一个生命周期的实例,它不是生命周期的类型,因此注释对我没有任何意义 .

我的意思是,我基本上了解最新情况(我认为):返回的 ~[&str] 与调用者的范围具有相同的生命周期,可能是 test_can_create_struct() 函数 . 那是因为(据我所知),函数 v1 是用来自调用函数的生命周期实例调用的 .

很混乱 .

然后我们有一些其他的例子:https://gist.github.com/bvssvni/8970459

这是一个片段:

impl<'a> Data<'a> {
  pub fn new() -> Data<'a> {
    Data { a: None, b: None }
  }

  pub fn a(&'a mut self, a: int) -> State<'a, Step1> {
    self.a = Some(a);
    State { data: self }
  }
}

现在我天真地假设 Data<'a> 意味着函数 a() 的生命周期实例是相同的 .

即,如果创建 Datalet blah = Data::new() )并调用 blah.a() ,则生命周期将从create调用继承;即,只要父 Data 对象返回的 State 对象将存在 .

......但显然这也是错的 . 所以我现在根本不知道生命变量的含义 .

救命!

1 回答

  • 19

    因此,回答这个问题的最简单方法就是退后一步,带您了解一生的实际情况 .

    让我们来看一个简单的功能:

    fn simple_function() {
      let a = MyFoo::new();
      println("{}", a);
    }
    

    在这个函数中,我们有一个变量 a . 与所有变量一样,这个变量会存在一段时间 . 在这种情况下,它一直存在于函数的末尾 . 当函数结束时, a 死亡 . a 的生命周期可以描述为从函数开始处开始,结束于函数结束时 .

    下一个函数将无法编译:

    fn broken_function() -> &MyFoo {
      let a = MyFoo::new();
      return &a;
    }
    

    当你做 &a 时,你是 borrowing a referencea . 然而,关于借贷的事情是,你应该把你借来的东西给回来 . Rust对此非常严格,并赢得了回报 . 如果你从isn 't around any more, you can'借来你的参考的东西返回参考,那就是没有 .

    它对我们的 broken_function 意味着什么,因为 a 在函数结束时死亡,引用无法转义函数,因为这将使它超过 a .

    下一步是这样的:

    fn call_fn() {
      let a = MyFoo:new();
      {
        let a_ref = &a;
        let b = lifetimed(a_ref);
    
        println!("{}", *b);
      }
    }
    
    fn lifetimed<'a>(foo: &'a MyFoo) -> &'a MyBar {
       return foo.as_bar();
    }
    

    这里有两个函数, call_fnlifetimed ,有's some subtle stuff going on here, so I' ll分解它 .

    call_fn 我首先创建 MyFoo 的新实例并将其分配给 a ,然后,我借用对 a 的引用并将其分配给 a_ref . 借用的东西是,当你进行借用时,生命周期信息会从你借来的变量转移到引用本身 . 所以现在 a_ref ,作为一个变量,有自己的生命周期,它在该内部范围的开始和结束处开始和结束,但 a_ref 的类型也有一个生命周期,一个从 a 转移过的生命周期 .

    具体的生命周期不能命名,但我们假设我们可以通过使用数字来完成它 . 如果 a 的生命周期是 #1 ,那么 a_reftype&'#1 MyFoo . 当我们将 a_ref 传递给 lifetimed 时,编译器会像其他类型参数一样填充生命周期参数 'a . lifetimed 的返回类型是具有相同生命周期的引用,因此编译器填充那里的空间 . 有效地拨打 lifetimed(foo: &'#1 MyFoo) -> &'#1 MyBar 的唯一电话 .

    这就是为什么生命周期出现在类型参数列表中,它们是类型系统的一部分,如果类型不匹配,那就是错误 . 编译器计算出函数编译所需的生命周期,因此您不必担心它,但不会在当前函数之外查看以获取更多信息 . 您需要使用参数告诉编译器您正在调用的函数,以便它知道一切正常 .


    NB :您可以明确命名一个生命周期 . 'static 这是整个程序的持续时间 .

相关问题