模块系统是 Rust 里最容易「看懂了、写不对」的部分。这篇用真实的编译器报错把规则一条条验证:什么算私有、pub 的几种范围、私有性在模块树里的方向,以及 mod 声明和磁盘文件是怎么对应的。
源码:
1 | mod bank {
2 | pub struct Account { pub owner: String, balance: i64 }
3 | impl Account {
4 | pub fn new(owner: &str) -> Self { Account { owner: owner.into(), balance: 0 } }
5 | pub fn deposit(&mut self, n: i64) { self.balance += n; }
6 | pub fn balance(&self) -> i64 { self.balance }
7 | }
8 | fn audit() {} // 私有函数
9 | }
10 | fn main() {
11 | let mut a = bank::Account::new("ann");
12 | a.deposit(50);
13 | println!("{} 的余额 {}", a.owner, a.balance());
14 | println!("{}", a.balance); // 私有字段
15 | bank::audit(); // 私有函数
16 | }
编译:失败
error[E0603]: function `audit` is private
--> <实验目录>/src/u14a.rs:15:11
|
15 | bank::audit(); // 私有函数
| ^^^^^ private function
|
note: the function `audit` is defined here
--> <实验目录>/src/u14a.rs:8:5
|
8 | fn audit() {} // 私有函数
| ^^^^^^^^^^
error[E0616]: field `balance` of struct `Account` is private
--> <实验目录>/src/u14a.rs:14:22
|
14 | println!("{}", a.balance); // 私有字段
| ^^^^^^^ private field
|
help: a method `balance` also exists, call it with parentheses
|
14 | println!("{}", a.balance()); // 私有字段
| ++
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0603, E0616.
For more information about an error, try `rustc --explain E0603`. 源码:
1 | mod outer {
2 | pub mod inner {
3 | pub(crate) fn crate_wide() -> &'static str { "pub(crate):整个 crate 可见" }
4 | pub(super) fn parent_only() -> &'static str { "pub(super):只有父模块 outer 可见" }
5 | pub fn everyone() -> &'static str { "pub:到处可见" }
6 | }
7 | pub fn call_parent_only() -> &'static str { inner::parent_only() }
8 | }
9 | use outer::inner::{self, everyone};
10 | fn main() {
11 | println!("{}", inner::crate_wide());
12 | println!("{}", everyone());
13 | println!("{}", outer::call_parent_only());
14 | }
编译:成功
运行(退出码 0):
pub(crate):整个 crate 可见
pub:到处可见
pub(super):只有父模块 outer 可见
源码:
1 | mod outer { pub mod inner { pub(super) fn parent_only() {} } }
2 | fn main() { outer::inner::parent_only(); }
编译:失败
error[E0603]: function `parent_only` is private
--> <实验目录>/src/u14c.rs:2:27
|
2 | fn main() { outer::inner::parent_only(); }
| ^^^^^^^^^^^ private function
|
note: the function `parent_only` is defined here
--> <实验目录>/src/u14c.rs:1:29
|
1 | mod outer { pub mod inner { pub(super) fn parent_only() {} } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0603`. 源码:
1 | mod parent {
2 | fn secret() -> &'static str { "父模块的私有函数" }
3 | pub mod child {
4 | pub fn peek() -> &'static str { super::secret() } // 子模块访问祖先的私有项
5 | fn hidden() -> &'static str { "子模块的私有函数" }
6 | }
7 | pub fn call_child_private() -> &'static str { child::hidden() } // 祖先访问子模块的私有项
8 | }
9 | fn main() { println!("{}", parent::child::peek()); println!("{}", parent::call_child_private()); }
编译:失败
error[E0603]: function `hidden` is private
--> <实验目录>/src/u14d.rs:7:58
|
7 | pub fn call_child_private() -> &'static str { child::hidden() } // 祖先访问子模块的私有项
| ^^^^^^ private function
|
note: the function `hidden` is defined here
--> <实验目录>/src/u14d.rs:5:9
|
5 | fn hidden() -> &'static str { "子模块的私有函数" }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0603`. 目录:src/main.rs src/util.rs src/net/mod.rs src/net/client.rs
$ cargo run -q
来自 util.rs
来自 net/client.rs
mod nothere; 但没有 nothere.rs:
Compiling modmissing v0.1.0 (<实验目录>/proj/modmissing)
error[E0583]: file not found for module `nothere`
--> src/main.rs:1:1
|
1 | mod nothere;
| ^^^^^^^^^^^^
|
= help: to create the module `nothere`, create file "src/nothere.rs" or "src/nothere/mod.rs"
= note: if there is a `mod nothere` elsewhere in the crate already, import it with `use crate::...` instead
crate、package、workspace 的关系见Crate、Package 与 Workspace。