函式呼叫中的生命週期
Lifetimes for function arguments and return values must be fully specified, but Rust allows lifetimes to be elided in most cases with a few simple rules. This is not inference -- it is just a syntactic shorthand.
- 凡是沒有生命週期註解的引數都會獲得一個註解。
- 如果只有一個引數生命週期,則會提供給所有未加註的回傳值。
- 如果有多個引數生命週期,但第一個是要給
self
,這個生命週期會提供給所有未加註的回傳值。
#[derive(Debug)] struct Point(i32, i32); fn cab_distance(p1: &Point, p2: &Point) -> i32 { (p1.0 - p2.0).abs() + (p1.1 - p2.1).abs() } fn nearest<'a>(points: &'a [Point], query: &Point) -> Option<&'a Point> { let mut nearest = None; for p in points { if let Some((_, nearest_dist)) = nearest { let dist = cab_distance(p, query); if dist < nearest_dist { nearest = Some((p, dist)); } } else { nearest = Some((p, cab_distance(p, query))); }; } nearest.map(|(p, _)| p) } fn main() { println!( "{:?}", nearest( &[Point(1, 0), Point(1, 0), Point(-1, 0), Point(0, -1),], &Point(0, 2) ) ); }
This slide should take about 5 minutes.
您可看到本例中隨意省略了 cab_distance
。
nearest
函式提供另一個函式範例,其引數具有多個需要明確註解的參照。
請試著調整簽章,「謊報」傳回的生命週期:
fn nearest<'a, 'q>(points: &'a [Point], query: &'q Point) -> Option<&'q Point> {
由於這不會執行編譯,表示編譯器已檢查註解是否有效。請注意,原始指標 (不安全) 的情況並非如此,這是不安全 Rust 的常見錯誤來源。
學生可能會詢問何時該使用生命週期。Rust 的借用「一律」具有生命週期。在大多數情況下,如果採取省略和型別推論的方式,表示您不必編寫這些內容。但在較複雜的情況下,生命週期註解可以協助解決模稜兩可的情況。一般而言,只要在有必要時複製值,即可輕鬆處理所擁有的資料,特別是在原型設計階段更是如此。