Rust 入门 Package Crate Module

Rust 的代码组织

  • 管理那些细节可以暴露, 那些细节是私有的
  • 管理作用域内哪些名称是有效的
  • ......

包(Package)

  • Package 是 Cargo 的特性
  • 可构建/测试/共享 Crate

Cargo.toml:

  • 一个Package 只能包含一个 Cargo.toml
  • Cargo.toml 用于描述如何构建这些 Crate

Crates:

  • 一个Package 只能包含0或者1个 library crate
  • 一个Package 可以包含任意数量的 binary crate
  • 一个Package 至少包含一个 crate

如何创建包:

> cargo new my_project
	Created binary (application) `my_project` package
# 使用 cargo 创建一个新项目时
# 会默认创建一个 package, package的名字就是你的项目名
# package 内默认包含一个 binary crate
# 这个 binary crate 的名字与package的名字相同

单元包(Crate)

  • 一个模块树
  • 它可以产生 library 或者 binary

Crate Type:

  • 共享库(library)
    • 共享库的 Crate Root 为 src/main.rs
  • 可执行文件(binary)
    • 可执行文件的 Crate Root 为 src/lib.rs
    • 如果将源代码文件放在 src/bin/ 下, 此时每个单独的文件都是一个 binary crate

Crate Root:

  • Crate Root 是一个源代码文件
  • Rust 编译器会从这个源代码文件开始, 组成你的Crate Root Module

Crate 的作用:

  • 将相关的功能组合到一个作用域内, 便于在项目件进项共享
  • 防止命名冲突

模块(Module)

  • 控制代码的组织, 作用域, 私有路径

Module 的作用:

  • 在一个 crate 内, 将代码进行分组
  • 增加可读性, 易于复用
  • 控制项目条目的私有性: public private

创建模块:

  • mod 关键字
  • 可嵌套
  • 可包含其他项(struct, enum, const, trait, function等)的定义
mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}

        fn seat_at_table() {}
    }
    mod serving {
        fn take_order() {}

        fn server_order() {}

        fn take_payment() {}
    }
}

私有边界:

  • 模块不仅可以组织代码, 还可以定义私有边界
  • 如果想把函数或者结构体设置为私有, 可以将它放入某个模块中
  • 默认情况下, Rust中的所有条目都是私有的
  • 父模块无法访问子模块中的私有条目, 子模块可以访问上级模块
  • 使用pub关键字可以将某些条目标记为公开的

路径(Path)

  • struct, function, module 等项 命名的方式
  • 路径分隔符使用::
  • 上级路径的表示符为super

绝对路径(absolute path)

  • 绝对路径从Crate Root 开始

相对路径(relative path)

  • 相对路径从 Self Path 开始

例子

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
    mod serving {
        fn take_order() {}
    }
}

fn main() {
    // 绝对路径
    crate::front_of_house::hosting::add_to_waitlist();
    // 相对路径
    front_of_house::hosting::add_to_waitlist();
}
fn serve_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        // 调用父路径中的方法
        super::serve_order();
    }

    fn cook_order() {}
}

fn main() {}

use 关键字

  • use 关键字将路径导入作用域内
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
    pub mod serving {
        fn take_order() {}
    }
}

// 绝对路径
use crate::front_of_house::serving;
// 相对路径
use front_of_house::hosting;

fn main() {
    hosting::add_to_waitlist();
    serving::take_order();
}

pub use 重新导出名称:

  • 使用 use 将路径导入到作用域后, 该名称在此作用域内是私有
  • 使用 pub sue 将路径导入到作用域后, 该条目可以被外部代码访问
pub use std::io::Result as IoResult;

使用嵌套路径引用

  • 如果要使用同一个包或模块下的多个条目, 可以使用嵌套语法进行导入
use std::{
    fmt::Result,
    io::Result as IoResult,
};

使用通配符

  • 使用 * 通配符可以把路径中所有的公共条目引入到作用域内
use std::collections::*;

as 关键字

  • as 关键字可以为引入的路径指定别名
use std::fmt::Result;
use std::io::Result as IoResult;

将模块拆分为多个文件

先来看一段 rust 代码

mod user {
    pub mod admin {
        pub fn login() {}
    }

    pub struct User {
        name: String,
        username: String,
        password: String,
        email: String,
    }

    impl User {
        pub fn new(name: &str, username: &str, password: &str, email: &str) -> User {
            User {
                name: String::from(name),
                username: String::from(username),
                password: String::from(password),
                email: String::from(email),
            }
        }

        pub fn name(&self) -> &str {
            &self.name
        }

        pub fn username(&self) -> &str {
            &self.username
        }

        pub fn password(&self) -> &str {
            &self.password
        }

        pub fn email(&self) -> &str {
            &self.email
        }
    }
}

use user::User;
use user::admin;

fn main() {
    let user = User::new("Tom", "TomFord", "Tom@%&", "tom@qq.com");
    println!("name: {}", user.name());
    println!("username: {}", user.username());
    println!("password: {}", user.password());
    println!("email: {}", user.email());
    admin::login();
}

将此代码内的 mod 拆分

  • 第一步:
    • src 目录下新建文件user.rs
    • 1 - 39 行代码复制到user.rs文件中
    • 删除外围包裹的mod user { }
// src/user.rs
pub mod admin {
    pub fn login() {}
}

pub struct User {
    name: String,
    username: String,
    password: String,
    email: String,
}

impl User {
    pub fn new(name: &str, username: &str, password: &str, email: &str) -> User {
        User {
            name: String::from(name),
            username: String::from(username),
            password: String::from(password),
            email: String::from(email),
        }
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn username(&self) -> &str {
        &self.username
    }

    pub fn password(&self) -> &str {
        &self.password
    }

    pub fn email(&self) -> &str {
        &self.email
    }
}
  • 第二步:
    • src目录下新建目录user
    • user目录下新建文件admin.rs
    • 2 - 4 行代码复制到admin.rs文件中
    • 删除外围包裹的mod admin{ }
// src/user/admin.rs
pub fn login() {}
  • 删除原来的模块实现, 构成最终的代码
// src/main.rs
mod user; // 修改此处

use user::User;
use user::admin;

fn main() {
    let user = User::new("Tom", "TomFord", "Tom@%&", "tom@qq.com");
    println!("name: {}", user.name());
    println!("username: {}", user.username());
    println!("password: {}", user.password());
    println!("email: {}", user.email());
    admin::login();
}
// src/user.rs
pub mod admin; // 修改此处

pub struct User {
    name: String,
    username: String,
    password: String,
    email: String,
}

impl User {
    pub fn new(name: &str, username: &str, password: &str, email: &str) -> User {
        User {
            name: String::from(name),
            username: String::from(username),
            password: String::from(password),
            email: String::from(email),
        }
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn username(&self) -> &str {
        &self.username
    }

    pub fn password(&self) -> &str {
        &self.password
    }

    pub fn email(&self) -> &str {
        &self.email
    }
}
// src/user/admin.rs
pub fn login() {}
如果对我分享的内容感兴趣的话  记得关注我得动态
求推荐  求收藏  求转发  求关注
posted @ 2021-06-22 17:35  Delayer  阅读(295)  评论(0编辑  收藏  举报