Перейти к основному содержимому
Модуль 6 · Урок 1 из 211/14 в курсе~15 min
Уроки модуля (1/2)

Срок службы и ссылки

В Rust каждая ссылка имеет время жизни, соответствующее области действия этой ссылки. В большинстве случаев время жизни неявно и выводится компилятором благодаря правилам исключения времени жизни. Однако, когда связь между временем жизни различных ссылок неоднозначна, мы должны явно их аннотировать.

Основная цель времен жизни — предотвратить висячие ссылки (ссылки на данные, которые уже были освобождены из памяти).


Синтаксис пожизненной аннотации

Пожизненные имена начинаются с апострофа (') и обычно представляют собой короткие строчные буквы (например, 'a). Аннотации времени жизни не меняют фактическое время жизни переменных, но они указывают компилятору взаимосвязь между допустимостью входных и выходных данных.

Например, если функция принимает два параметра ссылки на строку и возвращает ссылку на строку, и мы хотим, чтобы возвращаемая ссылка была допустимой, пока действительны оба входных параметра, мы используем:

Rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

Время жизни в структурах данных

Если структура содержит поле, которое является ссылкой, мы должны явно аннотировать время жизни этой ссылки, чтобы гарантировать, что экземпляр структуры не сможет пережить данные, на которые он ссылается:

Rust
struct ImportantExcerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().unwrap();
    let i = ImportantExcerpt {
        part: first_sentence,
    };
}

Статическое время жизни

Срок действия 'static — это особый срок действия, который длится всю продолжительность программы. Все строковые литералы (&str) неявно имеют время жизни 'static, поскольку они хранятся непосредственно внутри двоичного исполняемого файла.

Rust
let s: &'static str = "I have a static lifetime.";

Попробуйте сами

Упражнение 1. Самая длинная функция

Упражнение#rust.m6.l1.e1
Попыток: 0Загрузка…

Напишите функцию с именем longest<'a>, которая принимает два параметра: x типа &'a str и y типа &'a str и возвращает значение типа &'a str. Внутри функции используйте блок if/else, чтобы вернуть x, если его длина больше y, в противном случае верните y.

Загрузка редактора…
Показать подсказку

Объявите подпись с помощью `fn longest<'a>(x: &'a str, y: &'a str) -> &'a str`. Затем используйте `if x.len() > y.len() { x } else { y }`.

Решение доступно после 3 попыток

Упражнение 2. Структуры со ссылками

Упражнение#rust.m6.l1.e2
Попыток: 0Загрузка…

Определите структуру с именем Excerpt<'a>, содержащую одно поле с именем part типа &'a str. В основной функции создайте строковую переменную с именем text и создайте экземпляр переменной excerpt типа Excerpt, заимствовав ссылку на текст. Распечатать отрывок.часть.

Загрузка редактора…
Показать подсказку

Используйте `struct Excerpt<'a> { part: &'a str }`. В основном создайте его экземпляр с помощью `Excerpt { part: &text }`.

Решение доступно после 3 попыток

Упражнение 3. Статические ссылки

Упражнение#rust.m6.l1.e3
Попыток: 0Загрузка…

Объявите переменную с именем message с явной аннотацией типа для статического времени жизни (&'static str), присвоив ей строковый литерал. Распечатайте значение сообщения.

Загрузка редактора…
Показать подсказку

Используйте синтаксис `let message: &'static str = 'Messaggio statico!';`, чтобы явно указать время жизни статического сообщения.

Решение доступно после 3 попыток