Rust Package Crate Moudle


模块系统

  • Package 包:构建,测试,共享crate。
    • Crate 单元包:一个模块树,可以产生一个library或可执行文件。
      • Module 模块,use:代码组织,作用域,私有路径。
        • path:为struct, function, module 等项目命名的方式。

Package

包含:

  • 1个Cargo.toml
  • 0 - 1个library crate
  • 任意数量的 binary crate
  • 至少包含一个crate (library/binary)

Crate

crate的类型:binary/library

crate root

源代码文件,rust编译器从这里开始,组成crate的根module。

  • src/main.rs 是 binary crate 的 crate root。crate的名和package名相同。
  • src/lib.rs 是 library crate 的 crate root。crate的名和package名相同。

文件放在src/bin里面,代表每个文件都是单独的 binary crate。

crate 将相关的功能组合到一个作用域内,防止冲突。
eg: rand crate,访问时需要通过它的名字: rand

Moudle

在1个crate内,将代码进行分组。并能控制私有性。

建立module:

  • mod 关键字
  • 可嵌套
mod CAR {
    mod honda {
        fn MPV(){}
    }

    mod toyota {

    }
}

Path

类似python包管理。

绝对路径:从create开始,使用crate名或字面值crate。
相对路径:从当前模块开始,使用self, super或当前模块的标识符。

路径至少由一个标识符组成,标识符之间使用::

mod CAR {
    mod honda {
        fn MPV(){}
    }

    mod toyota {

    }
}

fn driver(){
    // 从根目录crate root开始查起
    crate::CAR::honda::MPV()

    // 同一级模块
    CAR::honda::MPV()
}

如果调用代码和模块代码总是一起的使用,就使用相对路径。反之则用绝对路径。

私有边界

模块默认是私有的,如果把函数或者结构体放进去,那么它就是私有的。rust中所有的条目(函数,方法,struct,enum,模块,常量)默认是私有的。

改成公共方法,关键字 pub

pub fn driver(){}

父级模块无法访问子模块中的私有条目。子模块可以使用所有祖先模块中的所有条目。

如果两个模块都是同级,那么就可以互相调用,不用公共。

mod CAR {
    pub mod honda {
        pub fn MPV(){}
    }

    mod toyota {

    }
}

pub fn driver(){
    // 这里可以直接调用CAR,因为是同级
    crate::CAR::honda::MPV();
    CAR::honda::MPV();
}

super

访问父级模块路径中的内容,类似文件系统中的..

super也是相对路径,访问上级目录。
super::someFunc()

pub struct

pub放在struct之前可以将结构体声明公有,但是里面的字段默认是私有的,也是加pub声明公有。

pub enum

pub放在enum之前可以将枚举声明公有,里面的变体默认是公有的。(enum就是为了让别人用的)

use

类似python的import,或者创建符号链接。

绝对路径:use crate::CAR::honda::MPV;
相对路径:use CAR::honda::MPV

use引用也需要遵守私有性规则。

  • 针对函数,一般只引入到父模块。
  • 针对struct, enum, 其他一般指定到完整路径,本身,如果引入两个,名字是一样的就父级。
    use std::collections::HashMap;

as

别名,和python一样
use std::io::Result as ioResult;

pub use

重导出,类似js的暴露。
使用use将路径(名称)导入到作用域内后,该名称在此作用域内是私有的。

pub use crate::CAR::honda::MPV;
引入了MPV,然后又导出了。

package 外部包

  1. cargo.toml添加依赖包。
  2. use 引入作用域。

标准库(std)也会被当作外部包。

嵌套路径

同一个包或模块引入多个条目。

路径相同的部分::{差异部分}
use std::{io, cmp::Ordering}

如果差异只是被包含的一个关系,就可以用self。一个引用是另外一个引用的子路径。

use std::io;
use std::io::Write;

// self是导入自己
use std::io::{self, Write};

* 通配符

use std::io::*

做测试的时候,所以被测试的模块引入到tests模块中。有时被用于预导入(prelude)模块。

拆分文件

模块定义时,如果模块名后面是;,而不是代码块,rust会从模块同名的文件中加载内容。

mod CAR;
rust就会在src目录下找CAR.rs。

多级目录下父级模块要变成文件夹。