- Mastering Rust
- Rahul Sharma Vesa Kaihlavirta
- 493字
- 2021-07-02 13:35:19
Directory as module
We can also create a directory that represents a module. This approach allows us to have submodules within modules as a file and directory hierarchy. Let's assume that we have a directory, my_program, that has a module named foo as a file foo.rs. It contains a type called Bar along with foo's functionality. Over time, the Bar APIs have grown in number and we wish to separate them as a submodule. We can model this use case with directory-based modules.
To demonstrate creating modules as directories, we have created a program in a directory named my_program. It has an entry point in main.rs and a directory named foo. This directory now contains a submodule within it named bar.rs.
Following is the structure of the directory my_program:
+ my_program
└── foo/
└── bar.rs
└── foo.rs
└── main.rs
To let Rust know about bar, we also need to create a sibling file named foo.rs alongside the directory foo/. The foo.rs file will contain mod declarations for any submodules created (here bar.rs) within the directory foo/.
Our bar.rs has the following content:
// my_program/foo/bar.rs
pub struct Bar;
impl Bar {
pub fn hello() {
println!("Hello from Bar !");
}
}
We have a unit struct Bar having an associated method hello. We want to use this API in main.rs.
Note: In the older Rust 2015 edition, submodules don't need a sibling foo.rs alongside the foo directory, and instead use a mod.rs file within foo to convey to the compiler that the directory is a module. Both of these approaches are supported in Rust 2018 edition.
Next, our foo.rs has the following code:
// my_program/foo.rs
mod bar;
pub use self::bar::Bar;
pub fn do_foo() {
println!("Hi from foo!");
}
We added a declaration of the module bar. Following that, we re-exported the item Bar from the module bar. This requires that Bar is defined as pub. The pub use part is how we re-export an item from a child module to be available from the parent module. Here, we used the self keyword to reference the module itself. Re-exports are mainly a convenience step when writing use statements, which helps remove the clutter when importing an item that is hidden away in nested submodules.
self is a keyword for relative imports. While it's encouraged to use absolute imports using crate, it is much cleaner to use self when re-exporting items from submodules in the parent module.
Finally main.rs uses both modules as:
// my_program/main.rs
mod foo;
use foo::Bar;
fn main() {
foo::do_foo();
Bar::hello();
}
Our main.rs declares foo and then imports the struct Bar. We then invoke the method do_foo from foo and also invoke hello on Bar.
There's more to modules than meets the eye and thus we cover some of the details about them in Chapter 7, Advanced Concepts. With modules explored, let's continue with Cargo.
- Mastering NetBeans
- 零基礎搭建量化投資系統:以Python為工具
- Progressive Web Apps with React
- Java FX應用開發教程
- Python網絡爬蟲從入門到實踐(第2版)
- PostgreSQL 11從入門到精通(視頻教學版)
- Mastering macOS Programming
- 硅谷Python工程師面試指南:數據結構、算法與系統設計
- 編程可以很簡單
- 自學Python:編程基礎、科學計算及數據分析(第2版)
- 遠方:兩位持續創業者的點滴思考
- R語言與網站分析
- Java程序設計基礎教程
- Netty 4核心原理與手寫RPC框架實戰
- 梔子貓的奇幻編程之旅:21天探索信息學奧賽C++編程