update summary
@@ -1,3 +1,16 @@
|
||||
# Summary
|
||||
|
||||
- [1 前言:为什么写这本书](./chapter_1.md)
|
||||
- [2 欢迎来到Rust的世界](./chapter_2.md)
|
||||
- [3 Rust基础]()
|
||||
- [3.1 变量和可变性](./chapter_3/chapter_3_1.md)
|
||||
- [3.2 基本数据类型](./chapter_3/chapter_3_2.md)
|
||||
- [3.3 函数](./chapter_3/chapter_3_3.md)
|
||||
- [3.4 注释](./chapter_3/chapter_3_4.md)
|
||||
- [3.5 控制流](./chapter_3/chapter_3_5.md)
|
||||
- [3.6 Rust内存模型](./chapter_3/chapter_3_6.md)
|
||||
- [3.7 所有权](./chapter_3/chapter_3_7.md)
|
||||
- [3.7.1 所有权介绍](./chapter_3/chapter_3_7_1.md)
|
||||
- [3.7.2 引用与借用](./chapter_3/chapter_3_7_2.md)
|
||||
- [3.7.3 Slice类型](./chapter_3/chapter_3_7_3.md)
|
||||
- [4 Rust使用技巧]()
|
||||
|
||||
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@@ -1,5 +1,5 @@
|
||||
# 2 欢迎来到Rust的世界
|
||||
## 2.1 为什么选择Rust
|
||||
## 2.1 为什么选择Rust
|
||||
### 2.1.1 Rust的历史与背景
|
||||
Rust是一种现代的系统编程语言,它注重性能、安全性和并发。Rust最初由Mozilla研究院的Graydon Hoare于2006年开始设计,最早的目标是为了解决C++在系统编程领域的一些痛点。在2010年,Mozilla正式开始支持这个项目,从那时起,Rust开始迅速发展并逐渐成为一个强大的编程语言。
|
||||
|
||||
@@ -17,7 +17,7 @@ Rust的设计理念是将系统编程的性能与安全性相结合。它的核
|
||||
- 2015年:Rust 1.0正式发布,稳定版本的Rust开始对外提供支持。
|
||||
- 2016年:Rust开始获得广泛关注,社区逐渐壮大。
|
||||
- 2018年:WebAssembly的推广使得Rust成为一个受欢迎的前端编程语言。
|
||||
|
||||
|
||||
3. 社区与生态系统
|
||||
|
||||
随着Rust的发展,其社区和生态系统也在不断壮大。Rust编程语言被广泛应用于各种领域,如网络编程、游戏开发、操作系统、嵌入式系统、区块链等。此外,Rust已经连续多年被Stack Overflow开发者调查评为最受欢迎的编程语言。
|
||||
@@ -114,7 +114,8 @@ Rust在系统工具和实用程序开发中也表现出色。Rust编写的工具
|
||||
1. 对于macOS和Linux用户
|
||||
|
||||
通过如下命令进行安装:
|
||||
```
|
||||
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
```
|
||||
|
||||
@@ -131,7 +132,8 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
### 2.2.2 验证安装
|
||||
|
||||
安装完成后,可以输入如下命令验证安装:
|
||||
```
|
||||
|
||||
```bash
|
||||
rustc --version
|
||||
```
|
||||
|
||||
@@ -140,12 +142,14 @@ rustc --version
|
||||
|
||||
### 2.3.1 创建一个新的Rust项目
|
||||
Rust使用Cargo作为官方的构建工具和包管理器,下面通过Cargo创建一个新的Rust项目:
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo new hello_world
|
||||
```
|
||||
|
||||
创建后,可以看到整个目录的结构如下:
|
||||
|
||||

|
||||

|
||||
|
||||
其中Cargo.toml是项目的配置文件,src为源代码目录,main.rs为主程序文件。
|
||||
|
||||
@@ -162,13 +166,13 @@ fn main() {
|
||||
### 2.3.3 编译并运行Hello, World程序
|
||||
运行程序需要进去到项目目录中,然后运行cargo run命令即可,步骤如下:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd hello_world
|
||||
cargo run
|
||||
```
|
||||
运行结果如下:
|
||||
|
||||

|
||||

|
||||
|
||||
### 2.3.4 理解Rust源码的基本结构
|
||||
下面简单介绍Rust源码的结构。
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## 3.2 基本数据类型(Basic Data Type)
|
||||
## 3.2 基本数据类型
|
||||
|
||||
Rust是静态类型语言,编译时就必须知道所有变量的类型。根据值以及其使用方式,Rust编译器通常能自动推导出变量的类型。
|
||||
Rust有两种数据类型子集,分别是:标量(scalar)类型和复合(compound)类型。
|
||||
@@ -76,7 +76,7 @@ Rust中的布尔型用bool表示,有两个可能的值,为true和false。布
|
||||
fn main() {
|
||||
// 定义方式
|
||||
let a: bool = true;
|
||||
let b: bool = false;
|
||||
let b: bool = false;
|
||||
|
||||
// 使用场景
|
||||
if a {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
## 3.3 函数(Function)
|
||||
## 3.3 函数
|
||||
|
||||
### 3.3.1. 函数定义
|
||||
fn关键字、函数名、函数参数名及其类型(如果有的话)、返回值类型(如果有的话)组成函数签名, 加上由一对花括号包含的函数体组成函数。例子如下:
|
||||
```Rust
|
||||
|
||||
@@ -94,4 +94,4 @@ fn main() {
|
||||
cargo doc --open
|
||||
```
|
||||
将打开上面代码里面文档注释生成的文档,如下图:
|
||||

|
||||

|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## 3.5 控制流(Control Flow)
|
||||
## 3.5 控制流
|
||||
|
||||
Rust中的控制流结构主要包括:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## 3.6 Rust内存模型
|
||||
### 3.6.1 Rust程序内存布局
|
||||

|
||||

|
||||
|
||||
上图是一张linux系统上Rust程序的内存布局图。在linux操作系统中,会划分固定的区域给内核使用,即上图中的内核空间;应用程序使用的是用户空间。
|
||||
|
||||
@@ -38,7 +38,7 @@ fn main() {
|
||||
}
|
||||
```
|
||||
对于上面的代码,在执行第17行和第18行的栈帧示意图如下:
|
||||

|
||||

|
||||
|
||||
这里需要注意的是两个帧对应同样的内存地址,这是因为在调用完f1函数后,其对应的栈帧释放(释放的实际意义就是这段内存可以被重新分配了),然后调用f2函数为其分配栈帧时从同样的地址进行分配。
|
||||
|
||||
@@ -51,4 +51,4 @@ Rust没有GC,但通过其独特的机制管理内存,程序员不用手动
|
||||
栈中存储的所有数据都必须占用(在编译时就)已知且固定的大小。编译时大小未知或可能变化的数据,存储在堆上。
|
||||
数据存放到栈上时,是直接将数据放到栈内存。
|
||||
当数据需要存放到堆上时,内存分配器则是根据数据的大小,在堆内存找到合适大小的空区域存放,把它标记为已使用,并返回一个表示该位置地址的指针。该指针存储在栈上,当需要访问具体的数据时,必须先访问指针,然后通过指针找到堆上的位置,从而访问数据。这个过程可以用下图表示:
|
||||

|
||||

|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
## 3.7.所有权(Ownership)
|
||||
## 3.7.所有权
|
||||
|
||||
- [所有权介绍](./chapter_3_7_1.md)
|
||||
- [引用与借用](./chapter_3_7_2.md)
|
||||
- [slice类型](./chapter_3_7_3.md)
|
||||
|
||||
@@ -26,12 +26,12 @@ fn main() {
|
||||
```Rust
|
||||
fn f() {
|
||||
let b = 1u32; // --------------------------------|
|
||||
let c = 2u32; //-----------| |
|
||||
let c = 2u32; //-----------| |
|
||||
// | |
|
||||
// | |---b的作用域范围
|
||||
println!("b = {:?}", b);// |--c的作用与范围 |
|
||||
println!("c = {:?}", c);// | |
|
||||
//-----------| -------------------|
|
||||
//-----------| -------------------|
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@@ -95,7 +95,7 @@ pub struct String {
|
||||
Vec类型的定义如下:
|
||||
```Rust
|
||||
pub struct Vec<T> {
|
||||
buf: RawVec<T>,
|
||||
buf: RawVec<T>,
|
||||
len: usize, // 长度
|
||||
}
|
||||
```
|
||||
@@ -118,7 +118,7 @@ struct String {
|
||||
更进一步的简化,可以得到String类型本质如下:
|
||||
```Rust
|
||||
struct String {
|
||||
ptr:NonNull<u8>,
|
||||
ptr:NonNull<u8>,
|
||||
cap: usize,
|
||||
len: usize,
|
||||
}
|
||||
@@ -139,7 +139,7 @@ fn main() {
|
||||
```
|
||||
在第2行定义String类型时,并不能确定最终字符串的大小,所以字符串内容本身应该存储在堆上。结合什么String类型的本质的内容,可以得到String类型的存储如下:
|
||||
|
||||

|
||||

|
||||
|
||||
String类型本身是三个字段(指针、长度、容量),在编译时是已知的大小,存储在栈上;String类型绑定的字符串(在上面代码中是“AB”)在编译时大小未知,是运行时在堆上分配内存,分配后的内存地址保存在String类型的指针字段中,内存大小保存在cap字段中,内存上存储的字符串长度保存在len字段中。
|
||||
|
||||
@@ -171,11 +171,11 @@ fn main() {
|
||||
```
|
||||
s是String类型,字符串“Hello world!”是存储在堆内存上的,其内存布局如下:
|
||||
|
||||

|
||||

|
||||
|
||||
当执行let s1 = s后,内存布局如下:
|
||||
|
||||

|
||||

|
||||
|
||||
当let s1 = s执行后,就发生了所有权的转移,String类型值的所有权从s转移到了s1。此时Rust认为原来的s不再有效。因此,上面代码第4行打开编译将会出错。
|
||||
|
||||
@@ -185,14 +185,14 @@ s是String类型,字符串“Hello world!”是存储在堆内存上的,
|
||||
只拷贝栈上的内容,就叫做浅拷贝。
|
||||
对于上面的String类型,执行let s1 = s后,只把s的ptr、len、cap中的值拷贝给s1的ptr、len、cap的值,这种就叫做浅拷贝。浅拷贝发生后,s的ptr和s1的ptr都指向同样的堆内存。内存布局如下:
|
||||
|
||||

|
||||

|
||||
|
||||
- 深拷贝
|
||||
|
||||
除了拷贝栈上的内容外,还拷贝堆内存中的内容,就叫做深拷贝。
|
||||
对于上面的String类型,执行let s1 = s后,除了把s的len、cap中的值拷贝给s1的len、cap外,还在堆上重新分配一块内存,将s的ptr指向的堆内存的内容拷贝到这块内存,然后s1的ptr指向这块内存,这种拷贝就叫做深拷贝。深拷贝发生后,s的ptr和s1的ptr指向不同的堆内存,但是堆内存中存储的内容一样。深拷贝发生后的内存布局如下:
|
||||
|
||||

|
||||

|
||||
|
||||
显然,**Rust中变量赋值(Rust中叫所有权转移)使用的是浅拷贝**。
|
||||
|
||||
@@ -227,11 +227,11 @@ Rust中,默认实现了Copy trait的类型有:
|
||||
```Rust
|
||||
fn main() {
|
||||
let s = String::from("hello");
|
||||
takes_ownership(s);
|
||||
takes_ownership(s);
|
||||
// println!("s: {:?}", s);//打开编译会报错,因为s的所有权在上一行已经转移到take_ownership函数中了
|
||||
|
||||
let x = 5;
|
||||
makes_copy(x);
|
||||
let x = 5;
|
||||
makes_copy(x);
|
||||
println!("x: {:?}", x);//不会报错,因为上一行将x传到makes_copy函数时会自动拷贝x的值到函数中
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ fn takes_ownership(some_string: String) {
|
||||
println!("{}", some_string);
|
||||
}
|
||||
|
||||
fn makes_copy(some_integer: i32) {
|
||||
fn makes_copy(some_integer: i32) {
|
||||
println!("{}", some_integer);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -40,7 +40,7 @@ fn print(s: String) -> String {
|
||||
```
|
||||
上面代码中,变量a、b、c、d的内存布局如下:
|
||||
|
||||

|
||||

|
||||
|
||||
**获取变量的引用,称之为借用** 。通过借用,允许使用被引用变量绑定的值,同时又没有移动该变量的所有权。前面的示例代码可以变成如下:
|
||||
```Rust
|
||||
@@ -178,13 +178,13 @@ fn main() {
|
||||
```
|
||||
|
||||
(2)限制二:**同一作用域,可变引用和不可变引用不能同时存在**。如下代码编译错误:
|
||||
```Rust
|
||||
```Rust
|
||||
fn main() {
|
||||
let mut s = String::from("hello");
|
||||
let r1 = &s; // 没问题
|
||||
let r2 = &s; // 没问题
|
||||
let r3 = &mut s; // 大问题,同时存在两个s的引用和一个可变引用
|
||||
println!("{}, {}", r1, r2);
|
||||
println!("{}, {}", r1, r2);
|
||||
println!("{}", r3);
|
||||
}
|
||||
```
|
||||
@@ -195,7 +195,7 @@ fn main() {
|
||||
|
||||
let r1 = &s; // 没问题
|
||||
let r2 = &s; // 没问题
|
||||
println!("{} and {}", r1, r2);
|
||||
println!("{} and {}", r1, r2);
|
||||
// 此位置之后 r1 和 r2 不再使用, 新编译器中: r1和r2离开了其作用域
|
||||
|
||||
let r3 = &mut s; // 没问题,因为r1和r2已不存在,没有同时存在对s的引用和可变引用
|
||||
@@ -240,11 +240,11 @@ int main()
|
||||
```
|
||||
在执行第14行前,其内存布局为:
|
||||
|
||||

|
||||

|
||||
|
||||
当执行第14行后,变成如下:
|
||||
|
||||

|
||||

|
||||
|
||||
第14行执行后,ptr就变成了一个悬垂指针(或者交悬垂引用),然后在第16行继续使用ptr,则会发生错误。
|
||||
|
||||
@@ -264,13 +264,13 @@ fn dangle() -> &String {
|
||||
*思考:为什么下面的代码是正确的* ?
|
||||
```Rust
|
||||
fn main() {
|
||||
let s = no_dangle();
|
||||
let s = no_dangle();
|
||||
println!("s = {:?}", s);
|
||||
}
|
||||
|
||||
fn no_dangle() -> String {
|
||||
let s = String::from("hello");
|
||||
s
|
||||
s
|
||||
} // 此处s虽然离开了函数这个作用域范围,但是它的所有权是被转移出去了,值并没有释放
|
||||
```
|
||||
|
||||
@@ -279,4 +279,3 @@ fn no_dangle() -> String {
|
||||
|
||||
- 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。
|
||||
- 引用必须总是有效的(不能是悬垂引用)。
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ fn main(){
|
||||
let arr_slice1 = &arr[..=1];
|
||||
println!("{:?}", arr_slice1); // [11,22];
|
||||
|
||||
let arr_slice2 = &mut arr[..=1];
|
||||
let arr_slice2 = &mut arr[..=1];
|
||||
arr_slice2[0] = 1111;
|
||||
println!("{:?}", arr_slice2);// [1111,22];
|
||||
println!("{:?}", arr);// [1111,22,33,44];
|
||||
@@ -44,7 +44,7 @@ fn main() {
|
||||
|
||||
&str和&String的内存布局如下:
|
||||
|
||||

|
||||

|
||||
|
||||
#### 3. 其它Slice
|
||||
数组的Slice,如下:
|
||||
@@ -63,4 +63,3 @@ fn main() {
|
||||
println!("b: {:?}", b);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||