< 返回我的博客

法号行颠 发表于 2025-01-20 09:28

rust 构建自己的库和模块

生成测试代码目录

通过命令行生成测试代码,其实就是一个调用rust库的二进制文件,这里我们设计库实现 say_hello()say_goodbye() 两个函数。

cargo new my_project

生成的目录结构

my_project/
├── Cargo.toml
└── src
    └── main.rs

生成自己的库

生成简单库

通过命令行生成自己的库文件:

cargo new mylib --lib

生成的目录结构

mylib/
├── Cargo.toml
└── src
    └── lib.rs

lib.rs 中添加内容

pub fn say_hello() {
    println!("Hello!");
}

pub fn say_goodbye() {
    println!("Goodbye!");
}

编译库

cargo build

修改my_project 的项目的配置文件 Cargo.toml ,在[dependencies] 中添加库的路径

[dependencies]
mylib={path = "../mylib"}

注:my_project 和 mylib 放在同一个目录下

修改 main.rs 代码,调用这两个函数:

  • 方法一 调用时使用完整路径
fn main() {
    mylib::say_hello();
    mylib::say_goodbye();
}

  • 方法二 先声明,再使用
use mylib::{say_hello, say_goodbye};
fn main() {
    say_hello();
    say_goodbye();
}

运行结果

$ cargo run
   Compiling mylib v0.1.0 (/home/anlj/work/src/rust/test/mylib)
   Compiling my_project v0.1.0 (/home/anlj/work/src/rust/test/my_project)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.10s
     Running `target/debug/my_project`
Hello!
Goodbye!

在库中增加模块

直接修改 lib.rs 文件

修改 mylib 中的 lib.rs 文件

mod greetings {
    pub fn say_hello() {
        println!("Hello!");
    }

    pub fn say_goodbye() {
        println!("Goodbye!");
    }
}

pub use greetings::*;

重新编译后库后,在 my_project 中执行 cargo run 可以看到结果——与上次运行结果相同。

添加新的模块文件

src 目录下创建一个新的文件,命名为 greetings.rs

pub fn say_hello() {
    println!("Hello!");
}

pub fn say_goodbye() {
    println!("Goodbye!");
}

修改 lib.rs

mod greetings;

pub use greetings::say_hello;
pub use greetings::say_goodbye;

重新编译后运行。

greetings.rs 的文件名即模块名

在 lib.rs 中声明的 pub use greetings::say_hello 和 pub use greetings::say_goodbye 才能在模块外部使用,否则不能被外部的程序使用。

将两个功能函数拆分成两个文件

src 目录下创建 greetings 目录,

在该目录下分别创建 hello.rs goodbye.rs 以及 mod.rs 文件

hello.rs

pub fn say_hello() {
    println!("Hello!");
}

goodbye.rs

pub fn say_goodbye() {
    println!("Goodbye!");
}

mod.rs

pub mod hello;
pub mod goodbye;

pub use hello::say_hello;
pub use goodbye::say_goodbye;

重新编译后运行。

文件目录结构如下:

mylib/
├── Cargo.lock
├── Cargo.toml
└── src
    ├── greetings
    │   ├── goodbye.rs
    │   ├── hello.rs
    │   └── mod.rs
    └── lib.rs

这里的文件夹 greetings 就是一个模块的名字,其所定义的内容由该文件夹下的 mod.rs 来定义。

这里我的理解是:

通过 lib.rs 定义了一个库;

通过文件夹 greetings 和 该文件夹下的 mod.rs 定义了一个模块:greetings;

通过 goodbye.rs 和 hello.rs 又分别定义了两个模块: hello & goodbye

使用 mod 关键字

使用 mod 关键字定义一个模块

目录结构如下:

mylib/
├── Cargo.lock
├── Cargo.toml
└── src
    ├── greetings
    │   └── mod.rs
    └── lib.rs

lib.rs

mod greetings;

pub use greetings::my_module;
pub use greetings::my_module::say_hello;
pub use greetings::my_module::say_goodbye;

mod.rs

pub mod my_module{
    pub fn say_hello(){
        println!("Hello");
    }

    pub fn say_goodbye(){
        println!("Goodbye");
    }
}

拆分模块

拆分后的目录结构

mylib/
├── Cargo.lock
├── Cargo.toml
└── src
    ├── greetings
    │   ├── mod.rs
    │   └── my_module
    │       ├── a.rs
    │       └── b.rs
    └── lib.rs

a.rs

pub mod my_module{
    pub fn say_hello(){
        println!("Hello");
    }
}

b.rs

pub mod my_module{
    pub fn say_goodbye(){
        println!("Goodbye");
    }
}

mod.rs

pub mod my_module {
    pub mod a;
    pub mod b;
}

lib.rs

mod greetings;

pub use crate::greetings::my_module::a;
pub use crate::greetings::my_module::b;

修改 my_project 中的 main.rs

use mylib::a::say_hello;
use mylib::b::say_goodbye;
fn main() {
    say_hello();
    say_goodbye();
}

mod 关键字相当于定义了一个新的模块,这时可以省去 mod.rs 文件

Tips

使用mod.rs 的路径符合旧的 Rust 模块命名约定。根据 Rust 的模块命名规范,在旧的风格中,如果一个模块的定义位于一个目录中,则使用 mod.rs 作为该目录下的模块文件名。

在新的 Rust 模块命名约定中,可以将模块的定义直接放在对应的目录下的一个以模块名命名的文件中,而无需使用 mod.rs 。这样可以更好地组织代码,并且使模块的结构更加清晰。

评论区

写评论

还没有评论

1 共 0 条评论, 1 页