English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Механизм жизни Rust — это ресурсный механизм управления, который равен по важности механизму собственности.
Эта концепция была введена, чтобы справиться с проблемами управления ресурсами в сложных типах систем.
Ссылка — это необходимый механизм для работы с сложными типами, так как данные сложных типов не могут быть легко скопированы и вычислены процессором.
Но часто это приводит к极其 сложным проблемам управления ресурсами, давайте начнем с понятия отложенной ссылки:
{ let r; { let x = 5; r = &x; } println!("r: {}", r); }
Этот код не может быть скомпилирован компилятором Rust, потому что значение, на которое ссылается r, было освобождено до использования.}
Зеленый диапазон 'a в верхнем рисунке represents период жизни r, а синий диапазон 'b represents период жизни x. Obviously, 'b значительно меньше 'a, ссылка должна быть в жизни значения.
Всегда в структуре мы используем String, а не &str, давайте объясним это на примере:
fn longer(s1: &str, s2: &str) -> &str { if s2.len() > s1.len() { s2 } else { s1 } }
Функция longer берет наибольшую строку из двух строковых срезов s1 и s2 и возвращает её ссылку. Но этот код не может быть скомпилирован, потому что возвращаемый значение ссылки может быть устаревшим:
fn main() { let r; { let s1 = "rust"; let s2 = "ecmascript"; r = longer(s1, s2); } println!("{} дольше", r); }
В этом программном коде, несмотря на сравнение, r используется, когда исходные значения s1 и s2 уже недействительны.もちろん, мы можем переместить использование r в диапазон жизни s1 и s2, чтобы предотвратить возникновение такой ошибки, но функция не может знать, что происходит за её пределами, она должна обеспечить, что передаваемые значения нормальны, и поэтому функция longer не может быть скомпилирована.
Комментарии жизни — это способ описать период жизни указателя.
Хотя это и не может изменить период жизни указателя, но можно声明 два указателя с одинаковым периодом жизни в подходящих местах.
Комментарии жизни начинаются с апострофа и следуют маленьким словом:
&i32 // Обычный указатель &'a i32 // Указатель с комментарием жизни &'a mut i32 // Указатель с комментарием жизни для изменяемого типа
Давайте изменим функцию longer с помощью комментариев жизни:
fn longer<'a>(s1: &'a str, s2: &'a str) -> &'a str { if s2.len() > s1.len() { s2 } else { s1 } }
Нам нужно использовать generics для объявления имени жизни, затем период жизни возвращаемого значения функции будет соответствовать двум параметрам, поэтому при вызове можно так написать:
fn main() { let r; { let s1 = "rust"; let s2 = "ecmascript"; r = longer(s1, s2); println!("{} дольше", r); } }
Результат выполнения двух предыдущих段 кода объединены:
ecmascript дольше
Внимание:Не забывайте принцип автоматического определения типа.
Это вопрос, оставленный ранее, и его ответы здесь:
fn main() { struct Str<'a> {} content: &'a str } let s = Str { content: "string_slice" }; println!("s.content = {}", s.content); }
Результат выполнения:
s.content = string_slice
Если у структуры Str есть методы определения:
impl<'a> Str<'a> { fn get_content(&self) -> &str { self.content } }
Возврат значения не имеет комментария жизненного цикла, но это не помешает. Это историческая проблема, в ранних версиях Rust не поддерживалась автоматическая оценка жизненного цикла, все жизненные циклы должны быть строго объявлены, но в основной стабильной версии Rust уже поддерживается эта функция.
Указатель жизненного цикла имеет особенность: 'static. Все строки, заключенные в двойные кавычки, представляют собой точные типы данных &'static str, lifetime 'static означает, что lifespan начинается с начала выполнения программы и заканчивается ее завершением.
use std::fmt::Display; fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str where T: Display { println!("Объявление! {}", ann); if x.len() > y.len() { x } else { y } }
Этот код взят из «Библии Rust」,является программой, которая использует механизмы генериков, характеристик и жизненного цикла, и не требует строгого выполнения, можно попробовать, так как рано или поздно это пригодится!