Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Времена жизни и заимствования: абстрактные правила

// 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 позволяет опускать их. См.: Неявное выведение времени жизни