研读Rust圣经解析——Rust learn-2
前言
本来我是想要使用英语来写的,但是想了一下很多意思可能用英语无法表述出来,由于我的第一语言目前依然是JAVA所以在解释的时候可能会沿用一些JAVA中的概念进行类比,后续我也会录制相关视频进行讲解
Cargo
Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库。(我们把代码所需要的库叫做依赖(dependencies))。
这是圣经上关于Cargo的介绍
简单来说Cargo就是Rust的”Maven|Gradle”,我们可以用它来:
- 创建项目
- 编译运行项目
- 检查项目问题
- 打包项目
- 发布项目
- 安装项目所需的依赖
- 项目模块导出导入
在我看来,以上七点就是Cargo的主要用处,接下来我们一一说明
创建项目
我们通过如下命令创建一个rust项目:
cargo new project_name
创建后我们将得到一个由project_name
为名称的项目
项目目录包含(以名称为test的项目为例):
|--test
|------|--src
|------|------|--main.rs
|------|--Cargo.lock
|------|--Cargo.toml
接下来我们说明一下这些包和文件
src入口包
在其他语言中src作为程序的主入口包,我们的代码主要放置在src下
main.rs代码入口文件
main:主要的
是我们的代码主入口文件,在main中含有rust的main函数
fn main(){
//...
}
而main函数自然是程序的主入口方法
Cargo.toml
是 Cargo 的配置文件就好比是Java中的pom.xml,前端中的package.json文件
其中我们可以对我们的项目进行配置,项目依赖进行引用,形如:
[package]
name = "ru2"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
虽然看起来这里目前很简单但是实际上我们有很多的东西可进行配置
配置说明
https://doc.rust-lang.org/cargo/reference/manifest.html#the-keywords-field
[package]
这是定义包的配置起始符,说明从该起始符开始我们对包的相关属性进行定义
配置名 | 类型 | 说明 | 例子 |
---|---|---|---|
name | String | 包名(项目名) | name="test" |
version | String | 包版本,默认为0.1.0(我们常使用0.0.0三位表示包版本,每次小版本更新则在最后一个数字上+1,大版本更新在第二个数字上+1,项目出现极大颠覆性修改在第一个数字上+1,当然这只是约定俗成的东西,并不具备极大的约束力) | version="0.0.1" |
authors | Array<String> |
包的作者 | authors = ["syf20020816@outlook.com"] |
edition | String | 包编译版本,目前2021是稳定版 | edition="2021" |
rust-version | String | Rust的版本 | rust-version = "1.56" |
description | String | 包的概述说明 | description="this is a test" |
documention | String | 托管crate的网站的URL的Doc文档地址 | documentation = "https://docs.rs/bitflags" |
readme | String | README文档的地址 | readme="README.md" |
homepage | String/IPAddr | 主页的站点的URL地址 | homepage="http://127.0.0.1:8989" |
license | String | 许可证的类型,常用ISO,MIT,Apache | license="MIT" |
license-file | String | 许可证文件 | license-file="LICENSE.txt" |
keywords | Array<Strng> |
关键词 | keywords=["test"] |
categories | Array<String> |
包字符串类型 | categories = ["command-line-utilities"] |
workspace | String | 配置此包将成为其成员的工作区 | workspace="lib/test" |
build | String | 指定包根目录中的一个文件,该文件是用于构建本机代码的构建脚本 | build = "build.rs" |
links | String | 指定要链接到的本机库的名称 | links="test" |
exclude | Array<String> |
发布时排除的文件 | exclude=["imgs/*"] |
include | Array<String> |
发布时包含的文件 | include=["imgs/*"] |
publish | String/Array<String> |
发布到那里去,false表示不发布 | publish = false |
…当然还有一些,不过我很少会去配置,以上为常用部分
[dependencies]
设置包的依赖库
我们会把从crates.io上面下载好的依赖放置在此起始符下
如下:
[dependencies]
rand="0.8.5"
Cargo.lock
这个文件是存放我们在cargo.toml中的依赖配置树的,究竟是说明意思呢,例如我们在依赖中引入了一个clap
[dependencies]
clap={version="4.2.1",features=["device"]}
你在.lock中就能看到如下内容
[[package]]
name = "clap"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3"
dependencies = [
"clap_builder",
"clap_derive",
"once_cell",
]
这里详细的展示了clap这个依赖的信息,以及它所依赖的依赖项,根据这个信息,cargo会自动下载所需要的其余所必须的依赖!
编译运行项目
我们通过如下命令编译运行rust项目:
cargo run
当我使用cargo run时,我们的代码会进行编译并且允许main.rs中main函数中的内容
检查项目问题
通过使用
cargo check
我们可以检测出我们代码中的错误,注意这些错误指的时编辑器中通过而真实运行编译无法通过的错误,这些错误可能在如Java等一些其他语言中并不常见,或者说很难发现,但是Rust中却是家常便饭,这得益于Rust解释器对于代码安全性的要求,宁可错杀不放过的原则,对于解释器无法理解的代码一律认为错误,而且会详细告诉你错误的内容,对于一些错误会提供解决方案
打包项目
cargo build
当我们打包项目后,会默认在target目录下生成debug目录,其中我们可以找到一个你设置项目名称的exe可执行文件
以下是默认的打包配置项:
[profile.dev]
opt-level = 0
debug = true
split-debuginfo = '...' # Platform-specific.
debug-assertions = true
overflow-checks = true
lto = false
panic = 'unwind'
incremental = true
codegen-units = 256
rpath = false
发布项目
cargo build --release
会在 target/release 而不是 target/debug 下生成可执行文件。这些优化可以让 Rust 代码运行的更快,不过启用这些优化也需要消耗更长的编译时间,默认发布时的优化等级是3——最高级,平时build的时候是0级,不过我们可以在[profile.release]的起始符下进行配置
以下是默认的配置:
[profile.release]
opt-level = 3
debug = false
split-debuginfo = '...' # Platform-specific.
debug-assertions = false
overflow-checks = false
lto = false
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
安装项目所需的依赖
cargo add depenenies_name
通过这个命令我们可以将我们需要的库安装到自己的项目中,进行管理和调用
项目模块导出导入
这并不是通过命令设置的而是通过toml的配置设置需要的导入和导出(exclude,include)