繁体   English   中英

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

[英]What does a scoped lifetime in rust actually mean?

所以,在:

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频道上看到的,但让我们想象就是这样,我们有一个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对象将存在。

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

救命!

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

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

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 ,编译器会填充a_ref参数'a就像它对其他类型参数一样。 lifetimed的返回类型是具有相同生命周期的引用,因此编译器填充了那里的空间。 有效地对lifetimed(foo: &'#1 MyFoo) -> &'#1 MyBar进行独特的调用lifetimed(foo: &'#1 MyFoo) -> &'#1 MyBar

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


注意 :您可以明确指定一个生命周期。 'static ,这是持续整个程序的事物的生命周期。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM