Lifetimes
Links:
- https://corrode.dev/blog/lifetimes/
- https://www.possiblerust.com/pattern/naming-your-lifetimes
- https://serde.rs/lifetimes.html
Время жизни
Метки времени жизни сообщают компилятору, как долго ссылка действительна.
Имя меток может быть абсолютно любым.
Правила элизии (неявного использования) меток времени жизни
- Каждая входная ссылка на функцию получает отдельное время жизни;
- Если есть ровно одно входное время жизни, оно применяется ко всем выходным ссылкам;
- Если есть несколько входных времен жизни, но одно из них —
&selfили&mut self, то время жизниselfприменяется ко всем выходным ссылкам.
Это означает, что вам нужно явно указывать времена жизни только в том случае, если у вас более одного входного времени жизни и ни одно из них не является &self или &mut self.
Заражение кода явными метками времени жизни
Если добавить метки времени жизни в структуру, например,
оптимизировать в &str для предотвращения выделения памяти и превратить в:
то теперь нужно добавлять метки во все методы, которые используют эту структуру:
Пример явного использования меток времени
В данном коде компилятор не может предсказать, что данные, на которые указывают ссылки x и y, будут живыми к моменту выхода из функции (выдаст ошибку). При этом та или иная ссылка нужны, в зависимости от выполнения условия (та, где данные длиннее), а понять какая можно будет лишь во время запуска приложения. Поэтому необходимо уверить компилятор, что обе ссылки останутся рабочими до конца работы функции:
Обход применения явных меток времени с помощью умных указателей Rc и Arc
Можно использовать умные указатели, Rc (подсчет ссылок) или Arc (атомарный подсчет ссылок), чтобы разделить владение данными. Таким образом, не нужно беспокоиться о явных временах жизни, сохраняя при этом затраты на клонирование данных близкими к нулю:
Пример с x и y можно переписать с применением Rc для примера:
Причины для явного использования меток времени жизни
Причин в современном Rust всего две:
- Существует узкое место в коде по производительности: Вы обнаружили медленный участок часто используемого кода, профилировали его и определили, что узкое место действительно вызвано выделением памяти. В этом случае имеет смысл использовать время жизни, чтобы избежать выделения памяти. (Альтернатива — реорганизовать ваш код, чтобы использовать лучший алгоритм и избежать «горячего пути» в первую очередь.)
- Код библиотек, от которого зависит код Вашего приложения, требует аннотаций времени жизни (пример - html5ever). Здесь мало что можно сделать, кроме как искать альтернативы, которые не требуют меток времени жизни.