# P27 7.1 Package、Crate、Module

# Rust 的代码组织

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

# Pacakge 和 Crate

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

# Cargo 的惯例

  • src/main.rs :
    • binary cratecrate root (rust 文件的入口)
    • crate 名与 package 名相同
  • src/lib.rs :
    • package 包含一个 library crate
    • library cratecrate root
    • crate 名与 package 名相闻
  • Cargocrate root 文件交给 rustc 来构建 librarybinary
  • 一个 Package 可以同时包含 src/main.rssrc/lib.rs
    • 一个 binary crate ,一个 library crate
    • 名称与 package 名相同
  • 一个 Package 可以有多个 binary crate :
    • 文件放在 src/bin
    • 每个文件是单独的 binary crate

# Crate 的作用

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

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

Module :
- 在一个 crate 内,将代码进行分组
- 增加可读性,易于复用
- 控制项目 (item) 的私有性。 publicprivate

  • 建立 module :
    • mod 关键字
    • 可嵌套
    • 可包含其它项 ( structenum常量trait函数 等) 的定义
module的定义 | lib.rs
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(){}
    }
}

# P28 7.2 路径

# 路径 (Path)

为了在 Rust 的模块中找到某个条目,需要使用路径,
路径的两种形式:
- 绝对路径:从 crate root 开始,使用 crate 名或字面值 crate
- 相对路径:从当前模块开始,使用 selfsuper 或当前模块的标识符
路径至少由一个标识符组成,标识符之间使用 :: 分隔。

路径的例子 | lib.rs
mod front_of_house {
    mod hosting{
        fn add_to_waitlist(){}
    }   
}
pub fn eat_at_restaurant(){
    crate::front_of_house::hosting::add_to_waitlist();
    
    front_of_house::hosting::add_to_waitlist();
}

# 私有边界 (privacy boundary)

模块不仅可以组织代码,还可以定义私有边界。
如果想把 函数或 struct 等设为私有,可以将它放到某个模块中。
Rust 中所有的条目 ( 函数方法structenum模块常量 ) 默认是私有的。
父级模块无法访问子模块中的私有条目
子模块里可以使用所有祖先模块中的条目

# pub 关键字

使用 pub 关键字来将某些条目标记为公共的

pub关键字 | lib.rs
mod front_of_house {
   pub mod hosting{
       pub fn add_to_waitlist(){}
    }   
}
pub fn eat_at_restaurant(){
    crate::front_of_house::hosting::add_to_waitlist();
    
    front_of_house::hosting::add_to_waitlist();
}

# P29 7.3 路径 super、pub、struct、enum

# super 关键字

super : 用来访问父级模块路径中的内容,类似文件系统中的。

super关键字 | lib.rs
fn serve_order(){}
mod  back_of_house{
    fn fix_incorrect_order(){
        cook_order();
        super::serve_order();
    }
    fn cook_order(){}
}

# pub struct

  • pub 放在 struct 前:
    • struct 是公共的
    • struct 的字段默认是私有的
pub struct | lib.rs
mod  back_of_house{
    pub struct Breakfast{
        // 公有字段
        pub toast: String,
        // 私有字段,因为没有加 pub 关键字
        seasonal_fruit: String,
    }
}
  • struct 的字段需要单独设置 pub 来变成公有
设置公有struct字段 | lib.rs
mod  back_of_house{
    pub struct Breakfast{
        pub toast: String,
        seasonal_fruit: String,
    }
    impl Breakfast{
    
        pub fn summer(toast: &str) -> Breakfast{
            Breakfast{
                toast: String::from(toast),
                seasonal_fruit: String::from("peaches"),
            }
        }
    }
}
    
pub fn eat_at_restaurant() {
    
    let mut meal = back_of_house::Breakfast::summer("Rye");
    // 可以通过编译,因为 toast 是公有的
    meal.toast = String::from("Wheat");
    println!("I‘d like {} toast please",meal.toast);
    // 无法通过编译,因为 seasonal_fruit 是私有的
    meal.seasonal_fruit = String::from("blueberries");
}

# pub enum

pub 放在 enum 前:
- enum 是公共的
- enum 的变体也都是公共的

pub enum | lib.rs
mod back_of_house{
    //enum 前面加上 pub 使其在外部可见,里面的变体则不需要加 pub
    // 公共的枚举里面的变体也都是公共的
    pub enum Appetizer{
        Soup,
        Salad,
    }
}
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Light Rain 微信支付

微信支付