因此,在:

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 channel 上看到的内容,但是可以想象是这种情况,并且我们有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()的生存期实例是相同的。

即,如果您创建Data(let blah = Data::new())并调用blah.a(),则生存期将从create调用继承;也就是说,返回的State对象将与父Data对象一样存在。

...但是显然这也是错误的。因此,我完全不知道生命周期变量现在到底意味着什么。

帮助!

最佳答案

因此,解决此问题的最简单方法是退后一步,逐步了解一生的实际状况。

让我们采取一个简单的功能:

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

在此函数中,我们有一个变量a。像所有变量一样,此变量会生存一定的时间。在这种情况下,它将保留到功能的末尾。函数结束时,a死亡。 a的生存期可以描述为从函数的开头开始,到函数的结尾结束。

下一个函数将无法编译:
fn broken_function() -> &MyFoo {
  let a = MyFoo::new();
  return &a;
}

当您执行&a时,您是借用a引用到。但是,关于借贷的事情是,您应该将借来的东西还给您。 Rust对此非常严格,不会让您拥有无法返回的引用。如果您从中借用了引用的东西不再存在,那么您将无法返回引用,并且该信息不可用。

这对我们的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这两个函数,这里有一些细微的事情,所以我将其分解。

call_fn中,我首先创建一个MyFoo的新实例并将其分配给a,然后借用一个对a的引用并将其分配给a_ref。借用的事情是,当您进行借用时,生命周期信息将从您要借用的变量转移到引用本身。因此,现在a_ref作为变量具有其自己的生存期,该生存期在该内部作用域的开始和结尾处开始和结束,但是a_ref的类型也具有生存期,即从a转移过来的生存期。

具体生命期无法命名,但是假装我们仍然可以使用数字来实现。如果a的生存期是#1,则a_ref类型&'#1 MyFoo。当我们将a_ref传递给lifetimed时,编译器将像其他类型参数一样填充生存期参数'alifetimed的返回类型是具有相同生存期的引用,因此编译器会在此处填充空间。有效地对lifetimed(foo: &'#1 MyFoo) -> &'#1 MyBar进行唯一调用。

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

注意::您可以明确命名一个生命周期。 'static,它是在程序整个长度上持续存在的事物的生命周期。

关于rust - 限定范围的 rust 生命周期实际上是什么意思?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22188088/

10-13 09:21