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
- 共享库的 Crate Root 为
- 可执行文件(binary)
- 可执行文件的 Crate Root 为
src/lib.rs
- 如果将源代码文件放在
src/bin/
下, 此时每个单独的文件都是一个 binary crate
- 可执行文件的 Crate Root 为
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() {}
如果对我分享的内容感兴趣的话 记得关注我得动态
求推荐 求收藏 求转发 求关注
求推荐 求收藏 求转发 求关注