Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

函式呼叫中的生命週期

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 的借用「一律」具有生命週期。在大多數情況下,如果採取省略和型別推論的方式,表示您不必編寫這些內容。但在較複雜的情況下,生命週期註解可以協助解決模稜兩可的情況。一般而言,只要在有必要時複製值,即可輕鬆處理所擁有的資料,特別是在原型設計階段更是如此。