模块使用

外部文件模块

通常,我们会在单独的文件中写模块内容,然后使用 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);
}
上一页