Уроки модуля (1/2)
Срок службы и ссылки
В Rust каждая ссылка имеет время жизни, соответствующее области действия этой ссылки. В большинстве случаев время жизни неявно и выводится компилятором благодаря правилам исключения времени жизни. Однако, когда связь между временем жизни различных ссылок неоднозначна, мы должны явно их аннотировать.
Основная цель времен жизни — предотвратить висячие ссылки (ссылки на данные, которые уже были освобождены из памяти).
Синтаксис пожизненной аннотации
Пожизненные имена начинаются с апострофа (') и обычно представляют собой короткие строчные буквы (например, 'a). Аннотации времени жизни не меняют фактическое время жизни переменных, но они указывают компилятору взаимосвязь между допустимостью входных и выходных данных.
Например, если функция принимает два параметра ссылки на строку и возвращает ссылку на строку, и мы хотим, чтобы возвращаемая ссылка была допустимой, пока действительны оба входных параметра, мы используем:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}Время жизни в структурах данных
Если структура содержит поле, которое является ссылкой, мы должны явно аннотировать время жизни этой ссылки, чтобы гарантировать, что экземпляр структуры не сможет пережить данные, на которые он ссылается:
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, поскольку они хранятся непосредственно внутри двоичного исполняемого файла.
let s: &'static str = "I have a static lifetime.";Попробуйте сами
Упражнение 1. Самая длинная функция
Напишите функцию с именем 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. Структуры со ссылками
Определите структуру с именем Excerpt<'a>, содержащую одно поле с именем part типа &'a str. В основной функции создайте строковую переменную с именем text и создайте экземпляр переменной excerpt типа Excerpt, заимствовав ссылку на текст. Распечатать отрывок.часть.
Показать подсказку
Используйте `struct Excerpt<'a> { part: &'a str }`. В основном создайте его экземпляр с помощью `Excerpt { part: &text }`.
Решение доступно после 3 попыток
Упражнение 3. Статические ссылки
Объявите переменную с именем message с явной аннотацией типа для статического времени жизни (&'static str), присвоив ей строковый литерал. Распечатайте значение сообщения.
Показать подсказку
Используйте синтаксис `let message: &'static str = 'Messaggio statico!';`, чтобы явно указать время жизни статического сообщения.
Решение доступно после 3 попыток