【Rust精华小册】3. 使用cargo创建Rust工程

本节内容只介绍Cargo的基本使用,以满足后面学习的需要。

使用cargo创建工程

Cargo是Rust语言的包管理器。Cargo下载Rust包的依赖项,编译包,生成可分发包,并将它们上传到crates.io(Rust社区的包仓库) 。

Rustup安装Rust环境时,就包含了cargo,可以使用cargo -V检测cargo是否可用。

Cargo使Rust中在工程层面区分了可执行文件和库,在使用Cargo创建crate时可以指定参数binlib以区分二者。crate是Rust中的package,他的概念类似js中的npm包或java中的maven包。lib类型的crate可以作为bin或者其它lib类型的依赖引入到项目中。

现在我们使用命令来分别创建这两种类型的crate:

shell 复制代码
# 创建可执行类型的项目
cargo new oskwgbin --bin
# 创建库类型的项目
cargo new oskwglib --lib

两种类型的基础目录结构如下,

css 复制代码
├─oskwgbin
│  │  .gitignore
│  │  Cargo.toml
│  └─src
│          main.rs
│
└─oskwglib
    │  .gitignore
    │  Cargo.toml
    └─src
            lib.rs

两种类型的项目唯一的区别是编译入口文件名不同,bin类型的是main.rslib类型的则是lib.rs

真实项目目录结构不会这么简单,我们需要看一个完整案例的目录结构是如何安排的。

工程目录结构

下面是Rust推荐的目录结构:

css 复制代码
.
├── build.rs
├── Cargo.lock
├── Cargo.toml
├── build.rs
├── src/
│   ├── lib.rs
│   ├── main.rs
│   └── bin/
│       ├── named-executable.rs
│       ├── another-executable.rs
│       └── multi-file-executable/
│           ├── main.rs
│           └── some_module.rs
├── benches/ 
│   ├── large-input.rs
│   └── multi-file-bench/
│       ├── main.rs
│       └── bench_module.rs
├── examples/
│   ├── simple.rs
│   └── multi-file-example/
│       ├── main.rs
│       └── ex_module.rs
└── tests/
    ├── some-integration-tests.rs
    └── multi-file-test/
        ├── main.rs
        └── test_module.rs
  • cargo.toml和cargo.lock是项目的配置文件,同时它必须位于项目的根目录下。
  • build.rs 在构建源码前,先运行该程序。例如:代码生成。
  • src是项目源码目录。其中的src/lib.rs是库项目特有的,src/main.rs是可执行文件项目特有的,如果有其它的可执行文件可以放到src/bin目录下面。
  • benches 目录存放基准测试文件。
  • examples 目录存放代码示例。
  • tests 目录存放集成测试文件的目录。

Cargo配置文件

Cargo.toml文件在crate中是。

介绍toml格式

toml格式是一种配置文件,与json、xml、yaml等配置格式类似,它可以表示数字、字符串、数组等类型。

作者声称有如下特点:

  • 语义明显易于阅读
  • 能无歧义地映射为哈希表
  • 易于解析成各种语言中的数据结构

对于一种声称配置文件格式的DSL,最值得我们关注的就是它如何表示基本类型。

toml 复制代码
1. 注释
# 这是一条 TOML 注释
2. 字符串
# 基本字符串
str1 = "hello"
# 字面量
str2 = 'world'
# 多行基本字符串
str3 = """hello
world"""
# 多行字面量字符串
str4 = '''hello
world
'''
3. 数字
int1 = 1
hex1 = 0xABAB
float1 = 3.14
4. 数组
intArray = [1,2,3]
strArray = ['a','b','c']
5. 表与内联表
[name] 
first = "Tom" 
last = "Preston-Werner" 

[point] 
x = 1 
y = 2 

[animal] 
type.name = "pug"

# 将上面的表使用等价的内联表表示
name = { first = "Tom", last = "Preston-Werner" } 
point = { x = 1, y = 2 } 
animal = { type.name = "pug" }

6. 表数组
[[fruits]] 
name = "apple"

# 等价的JSON结构
{ 
	"fruits": [ 
		{
			"name": "apple"
		}
	]
}

可以访问TOML中文网进阶学习 toml.io/cn/

常用配置选项

由于Cargo非常功能较多,因此配置也极为复杂,不过好在常用的配置项比较固定,下面我们只介绍常用的配置选项。

ini 复制代码
[package]
name = "helloworld"
version = "0.1.0"
edition = "2021"

[dependencies]
pkg_name = "0.1.0"

每个crate都有一个package表,package下面常用的属性有 name表示crate的名称,version表示crate的版本,edition表示使用的Rust规范是哪个版本。dependencies表示crate依赖了哪些crate,在运行或构建项目时会从网络上下载依赖包,其中pkg_name就是依赖包名称,"0.1.0"就是依赖包的版本。三方依赖包通常托管在crates.io,我们可以从仓库中搜索需要的依赖在项目中使用。

常用的cargo子命令说明

除了cargo new还有一些指令,方便我们操作项目。

shell 复制代码
cargo new # 创建项目
cargo run # 运行项目
cargo build # 构建项目
cargo clean # 清理构建
cargo doc # 利用文档生成文件
cargo test # 运行单元测试和集成测试代码

构建后产生了什么

当我们执行cargo build后,会在根目录下生成一个target文件夹。默认是debug模式下构建一个可执行文件或库,如果添加--release则以release模式构建。我们以一个可执行文件为例,看一下项目构建后生成了哪些内容。

python 复制代码
└─target
    │  .rustc_info.json
    │  CACHEDIR.TAG
    │
    ├─debug
    │  │  .cargo-lock
    │  │  helloworld.d
    │  │  helloworld.exe
    │  │  helloworld.pdb
    │  │
    │  ├─.fingerprint
    │  │  └─helloworld-1a74b84bc6952173
    │  │          bin-helloworld
    │  │          bin-helloworld.json
    │  │          dep-bin-helloworld
    │  │          invoked.timestamp
    │  │
    │  ├─build
    │  ├─deps
    │  │      helloworld.d
    │  │      helloworld.exe
    │  │      helloworld.pdb
    │  │
    │  ├─examples
    │  └─incremental
    │      └─helloworld-1a33b6wbbi9ss
    │          │  s-gss72k21aw-10hgpc3.lock
    │          │
    │          └─s-gss72k21aw-10hgpc3-7mz55f0sfn6hhne4vxrtfg6bz
    │                  1m145qd8oexia6nc.o
    │                  33ejn18tv7hxpbbm.o
    │                  3eq1bfsgiu76y9j4.o
    │                  3pfsb6ncovzingc4.o
    │                  4mkqlt86552igoa9.o
    │                  53eh6dzk21xnjl9a.o
    │                  dep-graph.bin
    │                  query-cache.bin
    │                  work-products.bin
    │
    └─release
        │  .cargo-lock
        │  helloworld.d
        │  helloworld.exe
        │  helloworld.pdb
        │
        ├─.fingerprint
        │  ├─helloworld-1a74b84bc6952173
        │  │      bin-helloworld
        │  │      bin-helloworld.json
        │  │      dep-bin-helloworld
        │  │      invoked.timestamp
        │  │
        │  └─json-f2a97d7a00cb1931
        │          dep-lib-json
        │          invoked.timestamp
        │          lib-json
        │          lib-json.json
        │
        ├─build
        ├─deps
        │      helloworld.d
        │      helloworld.exe
        │      helloworld.pdb
        │      json-f2a97d7a00cb1931.d
        │      libjson-f2a97d7a00cb1931.rlib
        │      libjson-f2a97d7a00cb1931.rmeta
        │
        ├─examples
        └─incremental

我们分别执行了cargo buildcargo build --release,在target目录下也产生了debug和release文件夹。构建命令会编译执行测试,用例,基准测试和依赖的其它crate等,并且每次执行都会增量编译,以提高编译速度。 在debug目录下生成了可执行文件,deps下是依赖的crate以及crate本身,examples是示例,incremental是增量编译目录。

关于Cargo还有很多内容可以说,不过上面这些内容已经足够应付日常开发和后续课程的理解,更多内容我希望在Cargo专题中在介绍。

相关推荐
Backstroke fish几秒前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five1 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序1 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫5412 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
前端每日三省3 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
小刺猬_9854 分钟前
(超详细)数组方法 ——— splice( )
前端·javascript·typescript
渊兮兮5 分钟前
Vue3 + TypeScript +动画,实现动态登陆页面
前端·javascript·css·typescript·动画
鑫宝Code5 分钟前
【TS】TypeScript中的接口(Interface):对象类型的强大工具
前端·javascript·typescript
爱吃青椒不爱吃西红柿‍️13 分钟前
华为ASP与CSP是什么?
服务器·前端·数据库
一棵开花的树,枝芽无限靠近你16 分钟前
【PPTist】添加PPT模版
前端·学习·编辑器·html