Выбрать главу

Рассмотрим следующий пример, в котором используется явная аннотация времён жизни:

// `print_refs` получает две ссылки на `i32`, имеющие различные

// времена жизни `'a` и `'b`. Оба этих времени жизни должны существовать

// не меньше, чем функция `print_refs`.

fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {

println!("x равно {} и y равно {}", x, y);

}

// Функция, не имеющая аргументов, но имеющая параметр времени жизни `'a`.

fn failed_borrow<'a>() {

let _x = 12;

// ОШИБКА: `_x` не живёт достаточно долго (`_x` does not live long enough)

//let y: &'a i32 = &_x;

// Попытка использования времени жизни `'a` для явного аннотирования

// внутри функции приведёт к ошибке, так как время жизни у `&_x` короче, чем

// у `y`. Короткое время жизни не может быть приведено к длинному.

}

fn main() {

// Создадим переменные, которые далее будут заимствованы.

let (four, nine) = (4, 9);

// Заимствуем (`&`) обе переменные и передадим их в функцию.

print_refs(&four, &nine);

// Любой ввод, который заимствуется, должен жить дольше, чем заимствующий.

// Другими словами, время жизни `four` и `nine` должно

// быть больше, чем время жизни `print_refs`.

failed_borrow();

// `failed_borrow` не содержит ссылок, заставляющих `'a` быть

// больше, чем время жизни функции, но `'a` больше.

// Поскольку время жизни никогда не ограничено, оно, по умолчанию, равно `'static`.

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

1

сокрытие позволяет скрыть аннотации времён жизни, но они всё же присутствуют.

Обобщения и замыкания

Сигнатуры функции с указанием времени жизни имеют некоторые ограничения:

   • любая ссылка должна иметь аннотированное время жизни

   • любая возвращаемая ссылка должна иметь то же время жизни, что входящая ссылка или static.

Кроме того, обратите внимание, что возврат ссылок из функции, которая не имеет ссылок во входных аргументах, запрещён, если он приведёт к возвращению ссылок на недопустимые данные. В следующем примере показаны некоторые действительные формы функции со временем жизни:

// Одна входная ссылка со временем жизни `'a`, которая

// будет жить как минимум до конца функции.

fn print_one<'a>(x: &'a i32) {

println!("`print_one`: x is {}", x);

}

// Использование времени жизни также возможно с изменяемыми ссылками.

fn add_one<'a>(x: &'a mut i32) {

*x += 1;

}

// Несколько элементов с различными временами жизни. В этом случае

// было бы хорошо, чтобы у обоих ссылок было одно время жизни `'a`,

// в более сложных случаях может потребоваться различное время жизни.

fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) {

println!("`print_multi`: x is {}, y is {}", x, y);

}

// Возврат переданных на вход ссылок допустим.

// Однако должен быть указано правильное время жизни.

fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x }

//fn invalid_output<'a>() -> &'a String { &String::from("foo") }

// Код написанный выше является недопустимым: время жизни `'a`

// должно жить после выхода из функции.

// Здесь, `&String::from("foo")` создает ссылку на `String`

// Данные будут удалены после выхода из области видимости, и

// будет возвращена ссылка на недопустимые данные.

fn main() {

let x = 7;

let y = 9;

print_one(&x);

print_multi(&x, &y);

let z = pass_x(&x, &y);

print_one(z);

let mut t = 3;

add_one(&mut t);

print_one(&t);

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX