The Rust Programming Language
The Rust Programming Language⌗
- Rust 开发工具
- Cargo: 内置的依赖管理器和构建工具
- Rustfmt: 确保开发者遵循一致的代码风格
- Rust Language Server 集成开发环境(IDE)提供强大的代码补全和内联错误信息功能
Chapter 1 - 入门指南⌗
-
1.1 - 安装
-
rustup: 一个管理Rust版本和相关工具的命令行工具
chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction) … ➜ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
检查安装是否正确
chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction) took 3.6s … ➜ rustc --version rustc 1.66.0 (69f9c33d7 2022-12-12)
-
-
1.2 更新与卸载
chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction) …
➜ rustup update
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: checking for self-updates
stable-x86_64-unknown-linux-gnu unchanged - rustc 1.66.0 (69f9c33d7 2022-12-12)
info: cleaning up downloads & tmp directories
chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction) …
➜ rustup self uninstall
-
1.3 Hello, World!
main.rs
fn main() { println!("hello, world!"); }
rustc
编译器编译Rust程序$ rustc main.rs
Rust是一种预编译静态类型(ahead-of-time compiled)语言
-
1.4 Hello, Cargo!
Cargo 是Rust的构建系统和包管理器,它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库.
检查是否安装了Cargo
➜ cargo --version
cargo 1.66.0 (d65d197ad 2022-11-15)
使用Cargo创建项目
chyiyaqing in github.com/rust-in-action-source-code/ch1 at aapc via ⬢ v18.12.1 …
➜ cargo new hello_cargo
Created binary (application) `hello_cargo` package
构建Cargo项目
chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on main [✘] via 🦀 1.66.0 …
➜ cargo build
Compiling hello_cargo v0.1.0 (/home/chyiyaqing/chyi/github.com/rust-in-action-source-code/ch1/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.43s
运行Cargo项目
chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes …
➜ ./target/debug/hello_cargo
Hello, world!
编译并运行Cargo项目
chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes …
➜ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/hello_cargo`
Hello, world!
检查代码
chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes …
➜ cargo check
Checking hello_cargo v0.1.0 (/home/chyiyaqing/chyi/github.com/rust-in-action-source-code/ch1/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.21s
发布构建Cargo
chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes …
➜ cargo build --release
Compiling hello_cargo v0.1.0 (/home/chyiyaqing/chyi/github.com/rust-in-action-source-code/ch1/hello_cargo)
Finished release [optimized] target(s) in 0.60s
Chapter 2 - 写个猜数字游戏⌗
- 在Rust中, 变量默认是不可变的
- associated function: 关联函数
- crates.io - The Rust community’s crate registry
- Cargo.lock - 文件确保构建是可重现的
- cargo update
Chapter 3 - 常见编程概念⌗
-
关键字 keywords
- 正在使用的关键字
- as - 强制类型转换,消除特定包含项的trait的歧义,或者对use语句中的项重命名
- async - 返回一个Future而不是阻塞当前线程
- await - 暂停执行知道Future的结果就绪
- break - 立刻推出循环
- const - 定义常量或不变裸指针 (constant raw pointer)
- continue - 继续进入下一次循环迭代
- crate - 在模块路径中,代指crate root
- dyn - 动态分发trait对象
- else - 作为if和if let 控制流结构的fallback
- enum - 定义一个枚举
- extern - 链接一个外部函数或变量
- false - 布尔字面值false
- fn - 定义一个函数或函数指针类型 (function pointer type)
- for - 遍历一个迭代器或实现一个traint或者指定一个更高级的生命周期
- if - 基于条件表达式的结果分支
- impl - 实现自有或trait功能
- in - for 循环语法的一部分
- let - 绑定一个变量
- loop - 无条件循环
- match - 模式匹配
- mod - 定义一个模块
- move - 使闭包获取其所捕获项的所有权
- mut - 表示引用,裸指针或模式绑定的可变性
- pub - 表示结构体字段,impl快或模块的共有可见性
- ref - 通过引用绑定
- return - 从函数中返回
- Self - 定义或实现trait的类型的类型别名
- self - 表示方法本身或当前模块
- struct - 定义一个结构体
- super - 表示当前模块的父模块
- trait - 定义一个trait
- true - 布尔字面值true
- type - 定义个类型别名或关联类型
- union - 定义个union并且是union声明中唯一用到的关键字
- unsafe - 表示不安全的代码、函数、trait或实现
- use - 引入外部空间的符号
- where - 表示一个约束类型的从句
- while - 基于一个表达式的结果判断是否进行循环
- 保留关键字
- abstract become box do final macro override priv try typeof unsized virtual yield
- 正在使用的关键字
-
变量和可变性
-
变量 变量默认是不可改变的(immutable), 可以在变量名前添加
mut
来使其可变. -
常量(constants) 常量是绑定到一个名称的不允许改变的值,声明常量使用
const
关键字, 不允许对常量使用mut. Rust对常量的命名约定是在单词之间使用全大写加下划线 -
隐藏(Shadowing) 定义一个与之前变量同名的新变量,第一个变量倍被第二个隐藏,当你使用变量名称时,编译器将看到第二个变量.
-
数据类型(data type)
-
标量(scalar) 标量(scalar)类型代表一个单独的值.
-
整型 整数是一个没有小数部分的数字,
isize
,usize
, 有符号数以补码形式存储. 有符号范围-
整数溢出(integer overflow) 当在debug模式编译时,Rust检查这类问题并使程序panic.
当在release构建中,Rust不检测溢出,会以一种被称为二进制补码回绕(two’s complement wrapping)的操作.简而言之,比此类型能容纳最大值的值会回绕到最小值
-
-
浮点型 Rust有两个原生的浮点数(floating-point numbers)类型,Rust的浮点数类型是f32和f64, 所有的浮点类型都是有符号.
Rust中所有数字类型都支持基本数学运算: 加法、减法、乘法、除法和取余.
-
布尔类型 Rust中的布尔类型有两个可能的值: true和false, Rust中的布尔类型使用bool表示
-
字符类型 Rust的char类型是语言中最原生的字母类型, 使用单引号声明
char
字面量, 使用双引号声明字符串字面值, Rust的char类型的大小为四个字节(four bytes),并代表一个Unicode标量值(Unicode Scalar Value)
-
-
复合类型(compound types) 复合类型可以将多个值组合成一个类型, Rust有两个原生的复合类型
-
元组(tuple) 元组是一个将多个其他类型的值组合进一个复合类型的主要方式 元组长度固定:一旦声明,其长度不会增大或缩小, 使用点号(.)后跟值的索引访问, 元祖的第一个索引值是0.
-
数组(array) 数组中的每个元素的类型必须相同,Rust中的数组长度是固定的
-
-
-
-
函数 Rust代码中的函数和变量名使用
snake case
规范风格,在snake case
中,所有字母都是小写并使用下划线分隔单词.Rust不关心函数定义所在的位置,只要函数被调用时出现在调用之处可见的作用域内就行- 参数(parameters) 参数(形参)是特殊变量,是函数签名的一部分.实参(arguments). Rust函数签名中,必须声明每个参数的类型。
- 语句和表达式 函数体由一系列的语句和一个可选的结尾表达式构成.语句(Statements)是执行一些操作但不返回值的指令,表达式(Expression)计算并产生一个值.表达式可以是语句的一部分. 表达式的结尾没有分号,如果在表达式的结尾加上分号,它就变成了语句,而语句不会返回值
- 函数的返回值 Rust中函数的返回值等同于函数体最后一个表达式的值.使用return关键字和指定值,可以从函数中提前返回,但大部分函数隐式的返回最后的表达式。
-
注释 (comments) Rust中,惯用的注释样式是以两个斜杠开始注释,并持续到本行的结尾.
Rust中另一种注释称为文档注释
-
控制流
- if表达式 Rust不会尝试自动将非布尔值转换为布尔值,必须总是显式地使用布尔值作为if的条件.
- 循环(loops)
- loop loop关键字告诉Rust一遍一遍执行一段代码直到明确要求停止
- while
- for
- break break关键字告诉程序何时停止循环
- continue continue关键字告诉程序跳过这个循环迭代中任何剩余代码,并转到下一个迭代
Chapter 4 - 认识所有权⌗
所有权是Rust最与众不同的特性,对语言的其他部分有着深刻含义.它让Rust无需垃圾回收(garbage collector)即可保障内存安全.
所有程序都必须管理其运行时使用计算机内存的方式。一些语言中具有垃圾回收机制,在程序运行时有规律地寻找不再使用的内存,在另一些语言中,程序员必须亲自分配和释放内存。Rust则选择了第三种方式:通过所有权系统管理内存。
- 所有权 (ownership)
Rust通过所有权系统管理内存,编译器在编译时会根据一系列的规律进行检查,如果违反任何这些规律,程序都不能编译. 在运行时,所有权系统的任何功能都不会减慢程序.
-
栈 Stack && 堆 Heap 堆和栈都是代码在运行时可供使用的内存.Stack 后进先出(last in, first out), 进栈(pushing onto the stack), 出栈(popping off the stack). 栈中所有数据都必须占用已知且固定的大小,在编译时大小未知或大小可变化的数据要改为存储在堆上。
-
所有权规则
- Rust中的每一个值都有一个所有者(owmer)
- 值的任一时刻有且只有一个所有者
- 当所有者(变量)离开作用域,这个值将被丢弃
-
变量作用域(scope)
FAQ⌗
- [1]: cargo build
Unable to update registry crates-io
$ vim ~/.cargo/config
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
[net]
git-fetch-with-cli=true