rust 中的package、crate、module

初学rust,对crate和mod的使用总是感到不太顺利,特此记录一下。

当我们用cargo 创建一个新项目时,默认就创建了一个package。

PS D:\test\rust_test> cargo new myproject

Creating binary (application) `myproject` package

note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

PS D:\test\rust_test>

crate:一个模块的树形结构,它形成了库或二进制项目。

module:一个 module 是用来组织代码的逻辑单位,用于拆分一个 crate 中的代码。

大致关系如下:

  • 1个Package里,至少要有1种Crate(要么是Library Crate,要么是Binary Crate)
  • 1个Package里,最多只能有1个Library Crate
  • 1个Package里,可以有0或多个Binary Crate
  • 1个Crate里,可以创建0或多个mod

场景一

先看一个最简单的例子:

rust 复制代码
mod database{
    pub fn mysql(){
        println!("I am mysql"); 
    }
}

fn main() {
    database::mysql();
}

运行:

PS D:\test\rust_test\myproject> cargo run

Compiling myproject v0.1.0 (D:\test\rust_test\myproject)

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.59s

Running `target\debug\myproject.exe`
I am mysql

说明:

1、需要加pub关键字将模块内的函数mysql()公开,否则main函数发现不到mysql()的存在。

2、main函数调用mysql时需要加上模块名称,database::mysql()。否则编译器也找不到mysql()。

场景二

再来看一个复杂点的例子:

rust 复制代码
mod database{
    pub fn mysql(){
        println!("I am mysql"); 
    }
    
    pub mod action{
        pub fn action_mysql(){
            super::mysql();     //子模块调用父模块,加super
        } 
    }

    pub fn print_mysql(){
        mysql();
    }
}

fn main() {
    database::print_mysql();
    use database::action;      //使用use简化调用路径
    action::action_mysql();
}

运行:

PS D:\test\rust_test\myproject> cargo run

Compiling myproject v0.1.0 (D:\test\rust_test\myproject)

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.17s

Running `target\debug\myproject.exe`

I am mysql

I am mysql

说明:

1、可以使用use关键字简化路径。

2、子模块调用父模块时,要加super关键字。

场景三

再来看一下多目录,多文件的场景:

在src目录下建立两个目录,folder_a和folder_b,然后folder_a下创建文件a1.rs, folder_b下创建文件b1.rs。目录结构看起来是下面这个样子的:

├─src

│ │ main.rs

│ ├─folder_a

│ │ a1.rs

│ └─folder_b

b1.rs

a1.rs内容如下:

rust 复制代码
pub mod inner{
    pub fn action_a1(){
        println!("action_a1");
    }
}

b1.rs内容如下:

rust 复制代码
pub mod b1{
    pub fn action_b1(){
        println!("action_b1");
    }
}

那么main.rs如何才能调用到action_a1()和action_b1()呢?需要做如下操作:

1、在src目录下新建三个文件,分别是lib.rs, folder_a.rs, folder_b.rs。

├─src

│ │ folder_a.rs

│ │ folder_b.rs

│ │ lib.rs

│ │ main.rs

│ ├─folder_a

│ │ a1.rs

│ └─folder_b

b1.rs

lib.rs内容如下:

rust 复制代码
pub mod folder_a;
pub mod folder_b;

folder_a.rs内容如下:

rust 复制代码
pub mod a1;

folder_b.rs内容如下:

rust 复制代码
pub mod b1;

2.修改main.rs文件

rust 复制代码
use myproject::folder_a;   //myproject为Cargo.toml里面的package name
use myproject::folder_b;

fn main() {
    folder_a::a1::inner::action_a1();
    folder_b::b1::b1::action_b1();       //两个b1, 第一个b1把b1.rs认为一个mod,第二个b1是pub mod b1{}
}

运行成功!

PS D:\test\rust_test\myproject> cargo run

Compiling myproject v0.1.0 (D:\test\rust_test\myproject)

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.50s

Running `target\debug\myproject.exe`

action_a1

action_b1

相关推荐
古城小栈8 小时前
Rust 迭代器产出的引用层数——分水岭
开发语言·rust
peterfei12 小时前
IfAI v0.2.8 技术深度解析:从"工具"到"平台"的架构演进
rust·ai编程
栈与堆16 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust
superman超哥16 小时前
双端迭代器(DoubleEndedIterator):Rust双向遍历的优雅实现
开发语言·后端·rust·双端迭代器·rust双向遍历
福大大架构师每日一题17 小时前
2026年1月TIOBE编程语言排行榜,Go语言排名第16,Rust语言排名13。C# 当选 2025 年度编程语言。
golang·rust·c#
superman超哥19 小时前
精确大小迭代器(ExactSizeIterator):Rust性能优化的隐藏利器
开发语言·后端·rust·编程语言·rust性能优化·精确大小迭代器
superman超哥19 小时前
惰性求值(Lazy Evaluation)机制:Rust 中的优雅与高效
开发语言·后端·rust·编程语言·lazy evaluation·rust惰性求值
古城小栈19 小时前
Rust IO 操作 一文全解析
开发语言·rust
superman超哥20 小时前
迭代器适配器(map、filter、fold等):Rust函数式编程的艺术
开发语言·rust·编程语言·rust map·rust filter·rust fold·rust函数式
superman超哥20 小时前
Iterator Trait 的核心方法:深入理解与实践
开发语言·后端·rust·iterator trait·trait核心方法