2016-04-12 37 views
1

這段代碼爲什麼編譯?爲什麼我可以對具有不同生命期的變量使用相同的生命週期標籤?

#[derive(Debug)] 
pub struct Foo<'a> { 
    pub x: &'a [&'a str], 
} 

fn main() { 
    let s = "s".to_string(); 
    let t: &str = s.as_ref(); 
    { 
     let v = vec![t]; 
     let foo = Foo { x: &v[..] }; 
     println!("{:?}", &foo); 
    } 
} 

在我Foo結構,我x字段包含&strs片。我對這些生命週期標籤的理解是,切片和個人擁有相同的生命週期。

但是,在我的示例中,&strt(在外部塊中)與容器切片(在內部塊中)的壽命不同。

回答

6

我對這些生命標籤的理解是,切片和個體&strs具有相同的生命週期。

這是一個常見的誤解。這實際上意味着必須有兩個適用於這兩者的生命週期。在實例化時,Foo結構的'a對應於let v = vec![t];之後的內部塊的行,因爲這是兩個變量共享的生命週期。

如果這種靈活性不存在,使用壽命將會非常痛苦。兩行定義的變量具有不同的實際生命週期(首先定義的變量超出了第二次定義的變量)。如果生命期必須實際匹配,我們總是必須在同一行上定義所有變量!

一些更詳細的信息可在RFC#738 — Variance

+0

感謝您的回答和鏈接!這非常有幫助 –

2

語法'a在兩種不同情況下的實際使用:

  • 標記環路
  • 指示結合

第一種情況,標記一個循環:

fn main() { 
    'a: loop { 
     println!("{}", 3); 
     break 'a; 
    } 
} 

在這裏,'a清楚地描繪了循環體的壽命,並且允許一次性打破多層循環。

第二,和更類似的情況中,使用'a來表示結合

fn<'a> susbtr(haystack: &'a str, offset: usize) -> &'a str; 

在這種情況下,壽命'a並不代表變量的實際的壽命,它代表了一個綁定參考變量的生命週期,並允許搭配在一起各種變量的界限。

注意,主叫方和被叫方解釋必然不同:

  • 從調用者的角度來看,'a上限,返回值將至少爲萬歲一個承諾作爲參數(甚至更長的時間,不能保證)
  • 從被叫用戶的角度(即substr),'a下限,檢查任何返回的值必須住至少只要作爲參數(甚至更長的時間,沒有必要)

當單個結合的用於多個壽命我們可以有自結合的方差並不代表實際的壽命,則編譯器將簡單地推斷的最低/最高結合有意義的局面:

  • 呼叫者得到最低上限可行(即,至少保證)
  • 呼叫者獲得最高下界可行(即,至少約束)

例如:

fn<'b> either(one: &'b str, two: &'b str, flag: bool) -> &'b str { 
    if flag { one } else { two } 
} 

可以與被稱爲:

fn<'a> call(o: &'a str, flag: bool) -> &'a str { 
    either(o, "Hello, World", flag) 
} 

這裏,o壽命是未知的(一些'a),同時"Hello, World"的生命週期是已知的('static),'static根據定義是壽命中較長的一個(它爲所有程序生活)。

  • call調用者只知道返回值居住至少只要o
  • call必須保證這一點,它提供o"Hello, World"either其中'b推斷爲'a之間的最下'static(因此'a
  • either只需返回與它的任一論點一樣長的東西;它不知道他們的一生可能會有所不同,並且不在意
相關問題