2014-04-15 59 views
9

我正在學習Rust中命名的生命週期,並且我很難理解它們在實現特徵時使用的表示。具體來說,我無法理解libserialize/hex.rs中的這段代碼。爲了簡潔起見,我刪除了一些評論。在特質實現中聲明時,生命週期引用了什麼?

pub trait ToHex { 
    fn to_hex(&self) -> ~str; 
} 

static CHARS: &'static[u8] = bytes!("abcdef"); 

impl<'a> ToHex for &'a [u8] { 
    fn to_hex(&self) -> ~str { 
     let mut v = slice::with_capacity(self.len() * 2); 
     for &byte in self.iter() { 
      v.push(CHARS[(byte >> 4) as uint]); 
      v.push(CHARS[(byte & 0xf) as uint]); 
     } 

     unsafe { 
      str::raw::from_utf8_owned(v) 
     } 
    } 
} 

我明白在煤焦定義'static一輩子,但我難倒在ToHex實現中定義的壽命。 命名生命期在特質的實現中代表什麼?

回答

8

在這種特殊情況下 - 並不多。 &[u8]不是完全指定的類型,因爲缺少生命週期,並且實現必須針對完全指定的類型。因此,實現參數化爲任意的(對於通用參數是無約束的)生存期'a

在這種情況下,您不再使用它。但是,有些情況下,您希望將函數參數或返回值限制爲相同的生命週期。

然後,您可以這樣寫:

impl<'a, T> ImmutableVector<'a, T> for &'a [T] { 
    fn head(&self) -> Option<&'a T> { 
     if self.len() == 0 { None } else { Some(&self[0]) } 
    } 
    … 
} 

這意味着,返回值將有相同的壽命爲self'a

順便說一句,只是把事情搞得一團糟,壽命可以手動寫在每個功能:

impl<'a, T> ImmutableVector<'a, T> for &'a [T] { 
    fn head<'a>(&'a self) -> Option<&'a T> { 
     if self.len() == 0 { None } else { Some(&self[0]) } 
    } 
    … 
} 

...這表明,必須指定要執行的是該類型的生命週期只是爲了確定完全是的類型。而且它允許您爲使用該生命週期的所有函數少寫一點。

+0

真棒,現在對我來說事情變得更加有意義。當我說*所有引用都需要定義一個生命週期時,我是否正確?但是編譯器會在某些情況下自動添加它,如函數參數?我認爲這可能是我錯過的部分。 – TwentyMiles

+0

確實如此。在大多數地方,它是自動確定的,如果沒有指定,內部函數參數是這種情況。 –

+0

不是第二個示例無效,因爲該方法的生命週期隱藏了impl上的生命週期?除了在現在的Rust中是非法的,它也不一樣。或者我錯了?我是Rust的新手,還沒有完全理解生活。 –

相關問題