首页 技术杂谈 正文
  • 本文约2407字,阅读需12分钟
  • 265
  • 0

Rust - Package\Crate\Module

摘要

在Rust语言中,探索Package、Crate和Module的层次结构,它们是构建和组织代码的基石。Package是项目的容器,Crate是编译单元,而Module则是代码的组织单元。这三者的协同,让Rust项目既模块化又易于管理。

1、Package\Crate\Module

1.1、Rust的代码组织

  • 代码组织主要包括
    • 那些细节可以暴露,那些细节是私有的
    • 作用域内那些名称有效
  • 模块系统
    • Package(包):Cargo的特性,让你构建、测试、共享crate
    • Crate(单元包):一个模块树,它可产生一个library或可执行文件
    • Module(模块)、use:让你控制代码的组织、作用域、私有路径
    • Path(路径):为struct、function或module等项命名的方式

1.2、Package和Crate

  • Crate的类型
    • binary
    • libary
  • Crate Root
    • 是源代码文件
    • Rust编译器从这里开始,组成你的Crate的根Module
  • 一个Package
    • 包含一个Cargo.toml,它描述了如何构建这些Crates
    • 只能包含0-1个libary crate
    • 可以包含任意数量的binary crate
    • 但必须至少包含一个crate(libary或binary)

1.3、Cargo的惯例

  • 一个Package可以同时包含src/main.rs和src/lib.rs
    • 一个binary crate , 一个libary crate
    • 名称与package名相同
  • 一个Package可以有多个binary crate
    • 文件放在src/bin
    • 每个文件是单独的binary crate

1.4、Crate的作用

  • 将相同功能组合到一个作用域内,便于在项目间进行共享,防止冲突
  • 例如 rand crate,访问它的功能需要通过它的名字:rand

1.5、定义module来控制作用域和私有性

  • Module
    • 在一个crate内,将代码进行分组
    • 增加可读性,易于复用
    • 控制项目的私有性。public、private
  • 建立module
    • mod关键字
    • 可嵌套
    • 可包含其他项(struct、enum、常量、trait、函数等)的定义
mod front_of_house{
    mod hosting{
        fn add_to_waitlist(){}
        fn seat_at_table(){}
    }

    mod serving{
        fn take_order() {}
        fn serve_order() {}
        fn take_payment() {}
    }
}

1.6、路径(Path)

  • 为了在Rust的模块中找到某个条目,需要使用路径
  • 路基的两种形式
    • 绝对路径:从crate root开始,使用crate名或字面值crate
    • 相对路径:从当前模块开始,使用self,super或当前模块的标识符
  • 路径至少由一个标识符组成,标识符之间使用::
mod front_of_house{
    mod hosting{
        fn add_to_waitlist(){}
        fn seat_at_table(){}
    }
}

// 通过路径调用模块
pub fn eat_at_restaurant(){
    // 通过绝对路径调用
    crate::front_of_house::hosting::add_to_waitlist();

    // 通过相对路径调用
    front_of_house::hosting::add_to_waitlist();
}

1.7、私有边界(privacy boundary)

  • 模块不仅可以组织代码,还可以定义私有边界

  • 如果想把函数或struct等设为私有,可以将它放到某个模块中

  • Rust中所有的条目(函数,方法,struct,enum,模块,常量)默认是私有的

  • 父级模块无法访问子模块中的私有条目

  • 子模块里可以使用所有祖先模块中的条目

mod front_of_house{
    // pub 关键字让它不是私有的
    pub mod hosting{
        pub fn add_to_waitlist(){}
        fn seat_at_table(){}
    }
}

// 通过路径调用模块
pub fn eat_at_restaurant(){
    // 通过绝对路径调用
    crate::front_of_house::hosting::add_to_waitlist();

    // 通过相对路径调用
    front_of_house::hosting::add_to_waitlist();
}

1.8、super关键字

  • super:用来访问父级模块路径中的内容,类似文件系统中的..
fn serve_order(){}

mod back_of_house{
    fn fix_incorrect_order() {
        cook_order();
        // 通过super调用serve_order
        super::serve_order();
    }
    fn cook_order() {
    }
}

1.9、use关键字

  • 可以使用use关键字将路径导入到作用域内
    • 任遵循私有性规则
  • use的习惯用法
    • 函数:将函数的父级模块引入作用域(指定到父级)
    • struct,enum,其他:指定完整路径(指定到本身)
mod front_of_house{
    // pub 关键字让它不是私有的
    pub mod hosting{
        pub fn add_to_waitlist(){}
        fn seat_at_table(){}
    }
}
// 通过use 调用 front_of_house
use crate::front_of_house::hosting;

// 调用struct的则使用完整路径
use std::collections::HashMap;

// 通过路径调用模块
pub fn eat_at_restaurant(){
    // 通过绝对路径调用
    crate::front_of_house::hosting::add_to_waitlist();

    // 通过相对路径调用
    front_of_house::hosting::add_to_waitlist();

    // 通过use引用后就可以在作用域内调用
    hosting::add_to_waitlist();

    // 调用Hashmap
    let mut map = HashMap::new();
    map.insert(1,2);
}

1.10、使用外部包(package)

  • Cargo.toml添加依赖的包(package)
  • use 将特定条目引入作用域
评论