【问题标题】:How to hide sibling modules from each other in Rust?如何在 Rust 中隐藏兄弟模块?
【发布时间】:2019-12-13 20:23:35
【问题描述】:

我有一个 Rust 模块 breakfast 包含两个子模块 eggbaconbreakfast 模块必须知道eggbacon,但是这两个孩子不需要,因此不应该知道彼此。

这就是我的代码现在的样子。早餐做好了,可惜eggbacon可以互相访问。

mod breakfast {
    pub fn make_breakfast() -> String {
        format!("{} and {}", egg::EGG, bacon::BACON)
    }

    mod egg {
        pub const EGG: &'static str = "egg";
    }

    mod bacon {
        pub const BACON: &'static str = "bacon";

        // Oh no! The bacon knows about the egg!
        // I want this to be a compile error.
        use super::egg::EGG;
    }
}

我可以通过使用可见性修饰符或重组模块以某种方式隐藏兄弟姐妹吗?还是我应该接受不需要的可见性?

实际上,这些模块位于单独的文件中,但我在这里将它们放在一个文件中以使示例更清晰。

【问题讨论】:

  • 似乎一个文件中的模块总是互相看到。对于单独文件中的模块,您可以尝试使用pub (super) 语法限制可见性。
  • @Zefick 感谢您的提示,将尝试一下!这些模块实际上是在单独的文件中,只需将它们放在一个文件中以使问题更清晰。
  • 据我所知,文件结构不会影响 Rust 看待程序模块结构的方式。例如mod breakfast { ... }mod breakfast; 具有单独的文件将始终功能完全相同。
  • @Zefick 实际上与单独的文件无关——像 Anders 那样对模块进行建模,并将它们分成单独的文件是完全相同的事情。
  • 现在我明白了。 pub(super) 使模块在超级模块及其所有子模块中可见。

标签: module rust private class-visibility


【解决方案1】:

这是设计使然:

Rust 的名称解析在命名空间的全局层次结构上运行。层次结构中的每个级别都可以被认为是某个项目。这些物品是上述物品之一,但也包括外部板条箱。可以将声明或定义新模块视为将新树插入到定义位置的层次结构中。 [...]

默认情况下,Rust 中的所有内容都是私有的,但有两个例外: pub Trait 中的关联项默认是公开的;默认情况下,pub 枚举中的枚举变体也是公共的。当一个项目被声明为 pub 时,它可以被认为是外部世界可以访问的。

鉴于项目是公共的或私有的,Rust 允许在两种情况下访问项目:

  • 如果一个项目是公开的,那么如果您可以从 m 访问该项目的所有父模块,则可以从某个模块 m 外部访问它。您还可以通过以下方式命名该项目再出口。 [...]
  • 如果一个项目是私有的,它可以被当前模块及其后代访问。

关于这方面的更多信息,请查阅The Reference的相关章节

【讨论】:

  • 有趣的是,在 C++ 和 Java 中,子类可以访问其父类可以访问的所有内容,因此在这方面,Rust 规则似乎与 C++ 和 Java 一致。我想知道是否有不同的语言行为。
猜你喜欢
  • 2022-11-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2020-06-13
  • 2021-11-05
  • 2023-03-31
  • 2017-09-25
相关资源
最近更新 更多