ํ•จ์ˆ˜ ํ˜ธ์ถœ์—์„œ์˜ ์ˆ˜๋ช…

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.