[英]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()
的生命周期實例是相同的。
即如果您創建一個Data
( let 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_fn
和lifetimed
,這里有一些微妙的東西,所以我會把它分解。
在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.