ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œμ˜ 수λͺ…

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> {

This won’t compile, demonstrating that the annotations are checked for validity by the compiler. Note that this is not the case for raw pointers (unsafe), and this is a common source of errors with unsafe Rust.

Students may ask when to use lifetimes. Rust borrows always have lifetimes. Most of the time, elision and type inference mean these don’t need to be written out. In more complicated cases, lifetime annotations can help resolve ambiguity. Often, especially when prototyping, it’s easier to just work with owned data by cloning values where necessary.