模块使用
外部文件模块
通常,我们会在单独的文件中写模块内容,然后使用 mod 关键字来加载那个文件作为我们的模块。比如,我们在 src
下新建了文件 aaa.rs
。现在目录结构是下面这样子:
foo
├── Cargo.toml
└── src
└── aaa.rs
└── main.rs
我们在 aaa.rs
中,写上:
pub fn print_aaa() {
println!("{}", 25);
}
在 main.rs
中,写上:
mod aaa;
use self::aaa::print_aaa;
fn main () {
print_aaa();
}
编译后,生成一个可执行文件。aaa.rs
中,没有使用 mod xxx {}
这样包裹起来,是因为 mod xxx;
相当于把 xxx.rs
文件用 mod xxx {}
包裹起来了。
use 语法
调用其它模块函数时, 通过 use
引入其所在的模块(module),使用关键字 use 简化路径 Paths, 类似文件系统中的 symbolic link。
use some_mod;
fn main() {
some_mod::some_fn();
}
调用其它模块结构体 struct, 枚举 enum,通过全路径引入,
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert(1, 2);
}
有命名冲突时, 引入父模块:
use std::fmt;
use std::io;
fn function1() -> fmt::Result {
// --snip--
}
fn function2() -> io::Result<()> {
// --snip--
}
或用 as
解决命名冲突的问题
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {
// --snip--
}
fn function2() -> IoResult<()> {
// --snip--
}
引入同一个模块 module 或包 package 中的多个元素
use std::{cmp::Ordering, io};
use std::io::{self, Write}; // 引入 std::io 和 std::io::Write
引入模块下所有共有元素, 需谨慎使用, 一般在测试时或预加载时使用:
use std::collections::*;
不同文件,子目录
// ↳ main.rs
mod greetings; // import greetings module
fn main() {
greetings::hello();
}
// ↳ greetings.rs
// ⭐️ no need to wrap the code with a mod declaration. File itself acts as a module.
pub fn hello() { // function has to be public to access from outside
println!("Hello, world!");
}
如果我们使用 mod 声明包装文件内容,它将充当嵌套模块。
// ↳ main.rs
mod phrases;
fn main() {
phrases::greetings::hello();
}
// ↳ phrases.rs
pub mod greetings { // ⭐️ module has to be public to access from outside
pub fn hello() {
println!("Hello, world!");
}
}
目录模块根目录中的 mod.rs 是目录模块的入口点。该目录根目录中的所有其他文件都充当目录模块的子模块。
// ↳ main.rs
mod greetings;
fn main() {
greetings::hello();
}
// ↳ greetings/mod.rs
pub fn hello() { // ⭐️ function has to be public to access from outside
println!("Hello, world!");
}
同样,如果我们使用 mod 声明包装文件内容,它将充当嵌套模块。
// ↳ main.rs
mod phrases;
fn main() {
phrases::greetings::hello();
}
// ↳ phrases/mod.rs
pub mod greetings { // ⭐️ module has to be public to access from outside
pub fn hello() {
println!("Hello, world!");
}
}
目录模块中的其他文件充当 mod.rs 的子模块。
// ↳ main.rs
mod phrases;
fn main() {
phrases::hello()
}
// ↳ phrases/mod.rs
mod greetings;
pub fn hello() {
greetings::hello()
}
// ↳ phrases/greetings.rs
pub fn hello() {
println!("Hello, world!");
}
如果需要从模块外部访问 phrases/greetings.rs
的元素,则必须将 greetings 模块导入为公共模块。
// ↳ main.rs
mod phrases;
fn main() {
phrases::greetings::hello();
}
// ↳ phrases/mod.rs
pub mod greetings; // ⭐️ `pub mod` instead `mod`
// ↳ phrases/greetings.rs
pub fn hello() {
println!("Hello, world!");
}
它无法将目录模块的子文件模块导入到 main.rs 中,因此您不能使用 mod phrases::greetings;
来自 main.rs。但是有一种方法可以通过将 hello 重新导出到 phrases 模块来将 phrases::greetings::hello()
简化导入:
// ↳ phrases/greetings.rs
pub fn hello() {
println!("Hello, world!");
}
// ↳ phrases/mod.rs
pub mod greetings;
pub use self::greetings::hello; //re-export greetings::hello to phrases
// ↳ main.rs
mod phrases;
fn main() {
phrases::hello(); //you can call hello() directly from phrases
}
这使您可以提供一个可能不直接映射到内部代码组织的外部接口。
父模块/同级引用
有时候我们希望引用父文件夹或者同级文件夹的模块,此时我们需要先在 main.rs 或者 lib.rs 中进行声明,然后再引用。
.
├── filemod.rs
├── foldermodule
│ ├── foldermodulefile.rs
│ └── mod.rs
├── lib.rs
├── main.rs
└── modtomod
├── mod.rs
└── something.rs
在 foldermodulefile 中我们需要引用 something 文件中的代码:
// something.rs
pub fn mod_to_mod() -> String {
String::from("Hey!! mod")
}
// main.rs
// till now we have seen using local modules in main file
// now let's see how to do mod to mod rather mod to main
// to use mod in other mod first we need to define called mod in
// main, so that caller mod can have it's scope
mod modtomod;
// foldermodulefile.rs
use uuid::Uuid;
// now let's call other local mod
use crate::modtomod::something;
pub fn folder_module_uuid() -> String {
Uuid::new_v4().to_string()
}
pub fn mod_to_mod_function() {
println!("hey!! from other mod {}", something::mod_to_mod());
}
使用外部包(External Packages)
在文件 Cargo.toml
中添加依赖 [dependencies]
, Cargo 从 crates.io下载所需要的依赖包.
[dependencies]
rand = "0.5.5"
引入 rand
中的 Rng
特性(trait)
use rand::Rng;
fn main() {
let secret_number = rand::thread_rng().gen_range(1, 101);
}