Времена жизни и заимствования: абстрактные правила
// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0
// Внутренний тип данных, чтобы было за что держаться.
pub struct Internal;
// Внешние данные.
pub struct Data(Internal);
fn shared_use(value: &Data) -> &Internal {
&value.0
}
fn exclusive_use(value: &mut Data) -> &mut Internal {
&mut value.0
}
fn deny_future_use(value: Data) {}
fn demo_exclusive() {
let mut value = Data(Internal);
let shared = shared_use(&value);
// let exclusive = exclusive_use(&mut value); // ❌🔨
let shared_again = shared;
}
fn demo_denied() {
let value = Data(Internal);
deny_future_use(value);
// let shared = shared_use(&value); // ❌🔨
}
fn main() {}
-
В этом примере правила анализатора заимствований переосмысляются: мы отходим от ссылок и переходим к смыслу в контекстах, не связанных с безопасностью памяти.
Ничего не изменяется, ничего не передаётся между потоками.
-
В анализаторе заимствований Rust есть три разных способа «взять» значение:
-
Владение значением
T. Значение освобождается при выходе из области видимости, если только оно не возвращается в другую область. -
Неизменяемая ссылка
&T. Допускает псевдонимы, но запрещает изменяемый доступ, пока используются неизменяемые ссылки. -
Изменяемая ссылка
&mut T. В каждый момент времени для значения может существовать только одна такая ссылка, но из неё можно создавать неизменяемые ссылки.
-
-
Спросите: почему две закомментированные строки в функциях
demoвызвали бы ошибки компиляции?demo_exclusive: потому что значениеsharedвсё ещё имеет псевдоним после того, как взята ссылкаexclusive.demo_denied: потому чтоvalueпотребляется в строке перед тем, как из&valueберётся ссылкаshared_again_again. -
Помните, что у каждой
&Tи&mut Tесть время жизни. Просто в большинстве случаев пользователю не нужно ни указывать его, ни думать о нём.Времена жизни мы редко указываем явно, потому что в большинстве случаев компилятор Rust позволяет опускать их. См.: Неявное выведение времени жизни