Rust编程与项目实战-箱

【图书介绍】《Rust编程与项目实战》-CSDN博客

《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com)

Rust编程与项目实战_夏天又到了的博客-CSDN博客

对于Rust而言,箱(crate)是一个独立的可编译单元,它编译后会生成一个可执行文件或者一个库。笔者一般不喜欢对专有名词进行翻译,如果硬要翻译,可称之为(分隔)箱。一个箱会将相关联的功能打包在一起,使得该功能方便在多个项目中分享。例如,标准库中没有提供但是在第三方库中提供的rand箱,它提供了随机数生成的功能,我们只需要将该包通过use rand;引入当前项目的作用域中,就可以在项目中使用rand的功能:rand::XXX。

同一个箱中不能有同名的类型,但是在不同箱中就可以。例如,虽然rand箱中有一个Rng trait,但是我们依然可以在自己的项目中定义一个Rng,前者通过rand::Rng访问,后者通过Rng访问,对于编译器而言,这两者的边界非常清晰,不会存在引用歧义。

我们通常所说的用rustc来编译一个文件,这种情况下编译器认为这个文件是一个箱,箱可以包含模块,模块可以定义在其他文件中,然后和箱一起编译。

箱是Rust中的一个编译单元,编译为二进制的可执行文件或库文件,可以通过Rust的编译器rustc的选项--crate-type来指定,默认情况下,rustc将从箱产生二进制可执行文件。

可执行的箱必须有一个main函数来定义程序执行入口。库箱则没有main函数,不会被编译为可执行程序,它提供一些外部使用的函数等,大部分情况大家提到箱一般指的是这类,就像其他语言中的library。

在Rust中,箱才是一个完整的编译单元。也就是说,rustc编译器必须把整个箱的内容全部读进去才能执行编译,rustc不是基于单个的.rs文件或者mod来执行编译的。另外要注意,箱之间不能出现循环引用。

10.1.1 创建crate库

我们将编写一个名为cat.rs的文件,然后编译为crate库文件。
【例10.1】 创建一个crate库

在某个目录下(这里是E:\ex\pkg\myprj\)新建一个文本文件,然后输入代码如下:

复制代码
pub fn public_function() {
    println!("called rary's `public_function()`");
}

fn private_function() {
    println!("called rary's `private_function()`");
}

pub fn indirect_access() {
    print!("called rary's `indirect_access()`, that\n> ");

    private_function();
}

定义了3个函数,第一个函数public_function的可见性是pub,那么外部调用者能直接调用该函数。第二个函数private_function没有明确写可见性,那么默认就是私有的,意味着外部调用者不能直接调用该函数,但它可以放到本库crate的其他可见pub函数中,比如这里的第三个函数indirect_access。

然后保存文件为cat.rs。打开命令行窗口,进行编译,命令如下:

复制代码
rustc --crate-type=lib cat.rs

rustc是Rust编程语言的编译器,由项目组开发并提供。通常,大多数Rust程序员都不会直接调用rustc,而是通过Cargo来完成,但我们也可以直接使用rustc来编译源文件,就像Linux中的gcc编译器一样。--crate-type=lib的意思是将源码文件编译成库crate,最后cat.rs就是要编译的源码文件。该命令执行后,将在同目录下生成一个crate库文件libcat.rlib,其中lib是自动加上的前缀,cat是源码文件名,rlib是后缀。

至此,一个crate库就开发完毕了。

10.1.2 创建可执行的crate

最简单的crate二进制就是把一个rs源码文件编译成二进制文件。如果是稍微复杂的情况,则是在二进制crate程序中调用crate库中的函数。
【例10.2】 创建简单的可执行crate程序

在某个目录下(这里是E:\ex\pkg\myprj\)新建一个文本文件,然后输入代码如下:

复制代码
fn main() {
    println!("Hello, world!");
}

代码很简单,就打印一句字符串"Hello, world!"。

打开命令行窗口并编译:

复制代码
rustc main.rs

rustc默认情况下将生成可执行的crate。编译成功后,将在同目录下生成可执行文件main.exe,直接运行它将打印"Hello, world!",结果如下:

复制代码
E:\ex\pkg\myprj>main.exe

Hello, world!

10.1.3 可执行crate调用crate库

将不同的人开发的不同程序最后一起联调,就是模块化编程的基本思想,这样并行开发的方式可以大大加快开发进度。现在我们创建一个main.rs文件,在该文件中调用libcat.rilb中的函数。
【例10.3】 可执行crate调用crate库

在某个目录下(这里是E:\ex\pkg\myprj\)新建一个文本文件,然后输入代码如下:

复制代码
fn main() {
    rary::public_function();

    // Error! `private_function` is private
    //rary::private_function();

    rary::indirect_access();
}

然后用下列命令编译:

rustc main.rs --extern cat=libcat.rlib --edition=2021

其中,--extern表示指定外部库的位置,此标志允许用户传递将链接到要构建的crate的外部crate的名称和位置,可以多次指定此标志。值的格式应为CRATENAME=PATH,这里是cat=libcat.rlib,即cat就是crate库名称(CRATENAME),库路径就是libcat.rlib,这里的路径只列出了文件名,说明就是在当前目录(即myprj目录)下。--edition表示指定要使用的版本,默认值为2015,这里用了较新的版本2021。

编译后将在同目录下生成可执行文件main.exe,然后执行main.exe这个文件:

复制代码
E:\ex\pkg\myprj>main
called rary's `public_function()`
called rary's `indirect_access()`, that
> called rary's `private_function()`

可见,打印的是libcat.rlib中的函数,这说明我们调用成功了。

相关推荐
whcyhhh1 小时前
头歌实践教学平台:数据科学与大数据技术导论(十八4)
大数据·开发语言·python
MC皮蛋侠客1 小时前
Tauri 2.x 系列(二):项目结构与前端框架——Vue、React 如何成为桌面前台
rust·tauri
65岁退休Coder1 小时前
LangGraph v1.2.9 核心概念 & 流程控制
后端·python·langchain
z落落1 小时前
C# Modbus-RTU 串口读写设备+CRC16+邮件告警
开发语言·c#
DS随心转小程序1 小时前
Gemini只能导出了一部分Word文档,很少的一部分,不是我这个窗口所有的对话内容?
开发语言·人工智能·c#·word·豆包·deepseek·ai导出鸭
江畔柳前堤1 小时前
消息队列:从直觉到精通的完整认知地图
开发语言·人工智能·算法·机器学习·ruby on rails·scala
程序员鱼皮1 小时前
爆火的《牛来》模型正式发布!DeepSeek 的排名又下降了。。
前端·后端·ai编程
格林威1 小时前
C# 相机图像配合频闪光源:实现高速稳定拍摄的几个方法
开发语言·网络·人工智能·数码相机·计算机视觉·c#·视觉检测
灯澜忆梦1 小时前
【基于GO的Web开发15】gin路由和路由组
前端·后端·golang·gin
陈老老老板2 小时前
2026 Web Scraping 教程:用 Codex + Bright Data 构建 Agent 原生数据采集流程
后端