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 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

use outer::Foo;

mod outer {
    pub struct Foo {
        pub val: i32,
        is_big: bool,
    }

    impl Foo {
        pub fn new(val: i32) -> Self {
            Self { val, is_big: val > 100 }
        }
    }

    pub mod inner {
        use super::Foo;

        pub fn print_foo(foo: &Foo) {
            println!("Is {} big? {}", foo.val, foo.is_big);
        }
    }
}

fn main() {
    let foo = Foo::new(42);
    println!("foo.val = {}", foo.val);
    // let foo = Foo { val: 42, is_big: true };

    outer::inner::print_foo(&foo);
    // println!("Is {} big? {}", foo.val, foo.is_big);
}
This slide should take about 5 minutes.
  • Этот слайд демонстрирует, что приватность полей структур основана на модулях. Студенты, пришедшие из объектно-ориентированных языков, могут привыкнуть к тому, что границей инкапсуляции служат типы, поэтому здесь показано, что Rust ведёт себя иначе, и как всё равно можно добиться инкапсуляции.

  • Обратите внимание, что поле is_big полностью контролируется Foo, что позволяет Foo определять, как оно инициализируется, и обеспечивать любые нужные инварианты (например, что is_big равно true только при val > 100).

  • Покажите, что вспомогательные функции можно определять в том же модуле (включая дочерние модули), чтобы получить доступ к приватным полям и методам типа.

  • Первая закомментированная строка показывает, что нельзя инициализировать структуру с приватными полями. Вторая показывает, что нельзя напрямую обратиться к приватным полям.

  • Перечисления не поддерживают приватность: варианты и данные внутри них всегда публичны.

Для дальнейшего изучения

  • Если студенты хотят узнать больше о приватности (или её отсутствии) в перечислениях, можно упомянуть #[doc(hidden)] и #[non_exhaustive] и показать, как их используют, чтобы ограничить то, что можно делать с перечислением.

  • Приватность модуля по-прежнему применяется, когда блоки impl находятся в других модулях (пример на playground).