Тривалість життя у викликах функцій
Тривалість життя аргументів функції та значень, що повертаються, має бути повністю вказана, але Rust дозволяє у більшості випадків не вказувати тривалість життя за допомогою кількох простих правил. Це не виведення - це просто синтаксичне скорочення.
- Кожному аргументу, який не має анотації тривалості життя, присвоюється одна.
- Якщо існує лише одна тривалість життя аргументу, то вона надається всім неанотованим значенням, що повертаються.
- Якщо існує декілька тривалостей життя аргументів, але перша з них призначена для
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() {
let points = &[Point(1, 0), Point(1, 0), Point(-1, 0), Point(0, -1)];
println!("{:?}", nearest(points, &Point(0, 2)));
}
У цьому прикладі cab_distance тривіально вилучено.
Функція nearest є ще одним прикладом функції з декількома посиланнями в аргументах, яка потребує явної анотації.
Спробуйте налаштувати сигнатуру на “брехню” про повернуту тривалість життя:
fn nearest<'a, 'q>(points: &'a [Point], query: &'q Point) -> Option<&'q Point> {
Це не скомпілюється, демонструючи, що компілятор перевіряє анотації на валідність. Зауважте, що це не стосується сирих вказівників (небезпечних), і це є поширеним джерелом помилок у небезпечному Rust.
Учні можуть запитати, коли слід використовувати тривалість життя. Rust запозичення завжди мають тривалість життя. Здебільшого, опускання та виведення типу означають, що їх не потрібно прописувати. У більш складних випадках, анотації тривалості життя можуть допомогти вирішити неоднозначність. Часто, особливо при створенні прототипів, простіше просто працювати з данними якими володіють, клонуючи значення там, де це необхідно.