2014-03-05 35 views
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,但我不明白这是什么代码实际上不会

功能基本参数化像普通的新生力量,但伴随一生,是我见过的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对象就会存在。

......但显然这也是错误的。所以我现在根本不知道寿命变量的意思。

帮助!

+0

Lifetimes *是*类型系统的一部分;他们不是实例。 –

回答

19

所以最简单的方法来回答这个问题将是退后一步,并引导你度过一生的实际。

让我们一个简单的函数:

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_reflifetimed时,编译器像使用其他类型参数一样填充生存期参数'alifetimed的返回类型是具有相同生命周期的引用,所以编译器填充了那里的空间。有效地拨打lifetimed(foo: &'#1 MyFoo) -> &'#1 MyBar

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


NB:有一个生命周期,你可以明确的名称。 'static这是持续整个程序长度的事物的生命周期。

+1

非常感谢您的解释,但是,当需要声明函数的生命周期时,您能举出一些真实生活的例子吗?我仍然无法捕捉到这个功能用例。 – gobwas

+0

我认为使用泛型类型很混乱。它真的只是添加一个标签来创建一个新的作用域/区域,泛型类型意味着一个新类型为每个'a,T组合例如1,T,2,T等实例化,并且1,T!= 2,T不是这样。 – user1496062

相关问题