代码写了二百多行了,虽然不多,但是统统放在一份源文件里,无论是阅读还是修改,已经让我觉得眼累。现在我要尝试使用 Rust 语言的模块功能为它们分家。
众所周知,Rust 的模块功能通常是配合它的搭档——项目构建工具 Cargo 来用,但我不打算如此。因为我不喜欢做一点小事情,就要大动干戈。这不是 Cargo 的问题,这是我的问题。
rskynet 项目
新建一个目录 rskynet,在该目录新建一份文件 rskynet.rs,其内容为
mod geometry;
use geometry::{sphere, mesh};
fn main() {
sphere::hi();
mesh::hi();
}
项目的名字就叫 rskynet。在 rskynet.rs 文件里,mod geometry
语句可「载入」 geometry 模块,use
语句可将 geometry 模块的子模块 sphere 和 mesh 作为命名空间。在 main
函数里,分别调用了 sphere 和 mesh 模块里的 hi
函数。
geometry 模块
在 rskynet 目录内,建立 geometry 目录,然后在该目录内新建一份文件 mod.rs,其内容如下:
pub mod sphere {
// 内容暂时为空
}
pub mod mesh {
// 内容暂时为空
}
现在,rskynet 目录的布局概览如下
rskynet
├── geometry
│ └── mod.rs
└── rskynet.rs
在 rskynet 目录内编译 rskynet.rs 并运行所得程序:
$ rustc rskynet.rs
$ ./rskynet
结果会输出
我是球体!
我是网格!
rustc 在编译 rskynet.rs 时,能够找到 geometry/mod.rs 文件,并且认为它是 geometry 模块,并且能够认出 geometry 模块还有两个子模块 sphere 和 mesh。
现在,可以得出以下结论:
- 模块可以是「目录/mod.rs」的形式;
- 在一个模块里,使用
pub mod 模块名 {...}
的语法可以构造该模块的子模块。
继续分割
能否将 sphere 和 mesh 模块的代码从 geometry/mod.rs 里抽出来,放在单独的文件里呢?试试看。
在 geometry 目录新建一份文件,名为 sphere.rs,其内容为
pub fn hi() {
println!("我是球体!");
}
再在 geometry 目录新建一份文件,名为 mesh.rs,其内容为
pub fn hi() {
println!("我是网格!");
}
然后将 geometry/mod.rs 内容修改为
pub mod sphere;
pub mod mesh;
最后重新编译 rskynet.rs 并运行所得程序,结果与上次相同。据此,可得结论:一份 .rs 文件是一个模块,若它被同目录内的 mod.rs 文件 pub mod
,则它会成为 mod.rs 对应模块的子模块。
访问父模块
倘若将 geometry/mod.rs 内容修改为
pub fn hi() {
println!(">>>");
}
pub mod sphere;
pub mod mesh;
在 sphere 和 mesh 模块里该如何调用它们父模块里的这个 hi
函数呢?
答案是,用 super
指代父模块。例如,将 sphere.rs 内容修改为
pub fn hi() {
super::hi();
println!("我是球体!");
}
在 main 函数里调用 sphere::hi
函数时,可输出
>>>
我是球体!
真正的 rskynet 项目
见 https://gitee.com/garfileo/rskynet
小结
谁知道我能坚持多久不用 Cargo。