Видимость и инкапсуляция
Как и элементы модуля, поля структур по умолчанию приватные. Приватные поля также видны в остальной части модуля (включая дочерние модули). Это позволяет инкапсулировать детали реализации структуры, контролируя, какие данные и функциональность видны извне.
// 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);
}
-
Этот слайд демонстрирует, что приватность полей структур основана на модулях. Студенты, пришедшие из объектно-ориентированных языков, могут привыкнуть к тому, что границей инкапсуляции служат типы, поэтому здесь показано, что Rust ведёт себя иначе, и как всё равно можно добиться инкапсуляции.
-
Обратите внимание, что поле
is_bigполностью контролируетсяFoo, что позволяетFooопределять, как оно инициализируется, и обеспечивать любые нужные инварианты (например, чтоis_bigравноtrueтолько приval > 100). -
Покажите, что вспомогательные функции можно определять в том же модуле (включая дочерние модули), чтобы получить доступ к приватным полям и методам типа.
-
Первая закомментированная строка показывает, что нельзя инициализировать структуру с приватными полями. Вторая показывает, что нельзя напрямую обратиться к приватным полям.
-
Перечисления не поддерживают приватность: варианты и данные внутри них всегда публичны.
Для дальнейшего изучения
-
Если студенты хотят узнать больше о приватности (или её отсутствии) в перечислениях, можно упомянуть
#[doc(hidden)]и#[non_exhaustive]и показать, как их используют, чтобы ограничить то, что можно делать с перечислением. -
Приватность модуля по-прежнему применяется, когда блоки
implнаходятся в других модулях (пример на playground).