diff --git a/src/chapter_3/chapter_3_2.md b/src/chapter_3/chapter_3_2.md index 7c52538..c433b0b 100644 --- a/src/chapter_3/chapter_3_2.md +++ b/src/chapter_3/chapter_3_2.md @@ -6,7 +6,7 @@ Rust是静态类型语言,编译时就必须知道所有变量的类型。根 标量类型包括:整型、浮点型、布尔类型和字符类型。 -### 3.2.1.1 整型和浮点型 +### 1. 整型和浮点型 Rust中的整型和浮点型如下: @@ -78,7 +78,7 @@ fn main() { } ``` -### 3.2.1.2 布尔型 +### 2. 布尔型 Rust中的布尔型用`bool`表示,有两个可能的值,为`true`和`false`。布尔类型使用的场景主要是条件表达式(控制流的内容),使用如下: @@ -103,7 +103,7 @@ fn main() { } ``` -### 3.2.1.3 字符类型 +### 3. 字符类型 Rust用`char`表示字符类型,用于存放单个unicode字符,占用4个字节空间。当存储`char`类型数据时,Rust会将其转换为utf-8编码的数据存储。`char`字面量是单引号包裹的任意单个字符,字符类型使用示例如下: @@ -119,7 +119,7 @@ fn main() { 复合类型是将多个值组合成一个类型。Rust有两个原生复合类型:元组和数组。 -### 3.2.2.1 元组 +### 1. 元组 圆括号以及其中逗号分割的值列表组成元组,定义一个元组方式如下: @@ -158,7 +158,7 @@ fn main() { } ``` -### 3.2.2.2 数组 +### 2. 数组 数组中的每个元素的类型必须相同,数组的长度是固定的,数组的定义方式如下: diff --git a/src/chapter_3/chapter_3_3.md b/src/chapter_3/chapter_3_3.md index 90c1368..1d50970 100644 --- a/src/chapter_3/chapter_3_3.md +++ b/src/chapter_3/chapter_3_3.md @@ -1,8 +1,8 @@ # 3.3 函数 -## 3.3.1. 函数定义 +## 3.3.1 函数定义 -fn关键字、函数名、函数参数名及其类型(如果有的话)、返回值类型(如果有的话)组成函数签名, 加上由一对花括号包含的函数体组成函数。例子如下: +`fn`关键字、函数名、函数参数名及其类型(如果有的话)、返回值类型(如果有的话)组成函数签名,加上由一对花括号(`{}`)包裹的函数体组成函数。例子如下: ```rust // 一个没有参数,也没有返回值的函数 @@ -53,26 +53,26 @@ fn main() { } ``` -## 3.3.2. 语句和表达式 +## 3.3.2 语句和表达式 Rust中,语句是执行一个操作但不返回值的指令,表达式则计算并产生一个值。 ```rust fn main() { - let a = 1u32; // "1u32"就是一个表达式, “let a = 1u32;”则是一个语句 - let b = a + 1;// “a + 1”就是一个表达式,“let b = a + 1;”则是一个语句 + let a = 1u32; // "1u32"就是一个表达式,而“let a = 1u32;”则是一个语句 + let b = a + 1; // “a + 1”就是一个表达式,而“let b = a + 1;”则是一个语句 // 下面的代码中, - // “ b + d ”是一个表达式, + // “b + d”是一个表达式 let c = { let d = 2u32; - b + d //注意:这里是没有分号的 + b + d // 注意:这里是没有分号的 }; // c = 4 } ``` -## 3.3.3. 函数返回值 +## 3.3.3 函数返回值 -- 使用return指定返回值,如下: +- 使用`return`指定返回值,如下: ```rust fn sum(a: u32, b: u32) -> u32 { @@ -88,22 +88,23 @@ fn main() { } ``` - 特别的return关键字不指定值时,表示返回的是(),如下: + 特别地,`return`关键字不指定值时,表示返回的是`()`,如下: + ```rust fn my_function() -> () { println!("some thing"); - return; //等价于 “return ()” + return; // 等价于“return ()” } ``` -- 不使用return关键字,将返回最后一条执行的表达式的计算结果,如下: +- 不使用`return`关键字,将返回最后一条执行的表达式的计算结果,如下: ```rust fn sum(a: u32, b: u32) -> u32 { println!("a is {:?}", a); println!("b is {:?}", b); - a + b //注意,是没有加分号的 + a + b // 注意,是没有加分号的 } fn main() { diff --git a/src/chapter_3/chapter_3_4.md b/src/chapter_3/chapter_3_4.md index 93f25ee..5e5444d 100644 --- a/src/chapter_3/chapter_3_4.md +++ b/src/chapter_3/chapter_3_4.md @@ -22,8 +22,8 @@ /* * 块注释: * 函数名:sum - * 参数: a,b - * 返回值类型: u32 + * 参数:a,b + * 返回值类型:u32 */ fn sum(a: u32, b: u32) -> u32 { a + b @@ -99,4 +99,4 @@ cargo doc --open 将打开上面代码里面文档注释生成的文档,如下图: -![注释](.././assets/1.png) +![注释](../assets/1.png) diff --git a/src/chapter_3/chapter_3_5.md b/src/chapter_3/chapter_3_5.md index 8f04c1a..9cb98a3 100644 --- a/src/chapter_3/chapter_3_5.md +++ b/src/chapter_3/chapter_3_5.md @@ -73,7 +73,7 @@ Rust中的控制流结构主要包括: ```rust fn main() { - // 一直循环打印 again + // 一直循环打印 again! loop { println!("again!"); } @@ -91,12 +91,14 @@ Rust中的控制流结构主要包括: counter += 1; if counter == 10 { - break; // 将终止循环 + break; // 将终止循环 } } } ``` + 上面的代码将打印10次,遇到`break`后终止循环。另外,`break`也可以返回值,如下: + ```rust fn main() { let mut counter = 0; @@ -125,7 +127,7 @@ Rust中的控制流结构主要包括: break; } if x % 2 == 0 { - continue; //将直接跳到下一轮循环 + continue; // 将直接跳到下一轮循环 } println!("{}", x); } @@ -134,7 +136,7 @@ Rust中的控制流结构主要包括: ## 3.5.3. while条件循环 -- `while`条件循环执行代码,当条件不满足后结束循环,如下: +- `while`条件循环执行代码,当条件不满足时结束循环,如下: ```rust fn main() { diff --git a/src/chapter_3/chapter_3_6.md b/src/chapter_3/chapter_3_6.md index 761617d..9f061a4 100644 --- a/src/chapter_3/chapter_3_6.md +++ b/src/chapter_3/chapter_3_6.md @@ -2,11 +2,12 @@ ## 3.6.1 Rust程序内存布局 -![注释](.././assets/2.png) +![注释](../assets/2.png) -上图是一张linux系统上Rust程序的内存布局图。在linux操作系统中,会划分固定的区域给内核使用,即上图中的内核空间;应用程序使用的是用户空间。 +上图是一张Linux系统上Rust程序的内存布局图。在Linux操作系统中,会划分固定的区域给内核使用,即上图中的内核空间;应用程序使用的是用户空间。 Rust程序使用的内存空间分为如下: + - 只读代码区(Instructions):存放可执行代码的区域。 - 只读数据区(Literals):存放代码的文字常量的区域。 - 静态数据区(Static Data):一般的静态函数、静态局部变量、静态全局变量的存放区域,在程序启动的时候初始化。 @@ -15,10 +16,9 @@ Rust程序使用的内存空间分为如下: ## 3.6.2 栈和堆 -### 1.栈和栈帧 +### 1. 栈和栈帧 -“栈和栈帧属于操作系统的概念,由操作系统进行管理,栈空间以后进先出的顺序存储数据。将数据放到栈上就做入栈,将数据移出栈就做出栈。 -每次调用函数时,操作系统会在栈顶创建一个栈帧来保存函数的上下文数据(主要是函数内部声明的局部变量),函数返回时返回值也会存储在该栈帧中。当函数调用者取得该函数返回值后,栈帧会被释放。”引用自《Rust入门秘籍》。 +> “栈和栈帧属于操作系统的概念,由操作系统进行管理,栈空间以后进先出的顺序存储数据。将数据放到栈上就做入栈,将数据移出栈就做出栈。每次调用函数时,操作系统会在栈顶创建一个栈帧来保存函数的上下文数据(主要是函数内部声明的局部变量),函数返回时返回值也会存储在该栈帧中。当函数调用者取得该函数返回值后,栈帧会被释放。”引用自《Rust入门秘籍》。 ```rust fn f1(a: i32, b: i32) -> i32 { @@ -42,17 +42,17 @@ fn main() { } ``` -对于上面的代码,在执行第17行和第18行的栈帧示意图如下: +对于上面的代码,在执行`let _r = f1(a, b);`和`let _r = f2(a, b);`这两行代码时的栈帧示意图如下: -![注释](.././assets/3.png) +![注释](../assets/3.png) -这里需要注意的是两个帧对应同样的内存地址,这是因为在调用完f1函数后,其对应的栈帧释放(释放的实际意义就是这段内存可以被重新分配了),然后调用f2函数为其分配栈帧时从同样的地址进行分配。 +这里需要注意的是两个帧对应同样的内存地址,这是因为在调用完`f1`函数后,其对应的栈帧释放(释放的实际意义就是这段内存可以被重新分配了),然后调用`f2`函数为其分配栈帧时从同样的地址进行分配。 ### 2. 堆 -堆空间和栈空间不同,不由操作系统管理,在需要时申请,不需要时释放。申请和释放堆内存是一件困难的事情,尤其当程序代码较多时。只申请堆内存而不释放会造成内存泄露,内存泄露过多会造成内存耗尽而崩溃。错误的释放在使用的内存也会造成程序运行错误(或直接无法运行)。 +堆空间和栈空间不同,不由操作系统管理,在需要时申请,不需要时释放。申请和释放堆内存是一件困难的事情,尤其当程序代码较多时。只申请堆内存而不释放会造成内存泄露,内存泄露过多会造成内存耗尽而崩溃。错误地释放在使用的内存也会造成程序运行错误(或直接无法运行)。 -有些编程语言使用提供垃圾管理回收器(GC)来自动回收不再使用的堆内存,有些语言必须完全由程序员在代码中手动申请和释放内存。 +有些编程语言提供垃圾管理回收器(GC)来自动回收不再使用的堆内存,有些语言必须完全由程序员在代码中手动申请和释放内存。 Rust没有GC,但通过其独特的机制管理内存,程序员不用手动申请和释放堆内存。 @@ -60,8 +60,8 @@ Rust没有GC,但通过其独特的机制管理内存,程序员不用手动 栈中存储的所有数据都必须占用(在编译时就)已知且固定的大小。编译时大小未知或可能变化的数据,存储在堆上。 -数据存放到栈上时,是直接将数据放到栈内存。 +数据存放到栈上时,是直接将数据放到栈内存的。 当数据需要存放到堆上时,内存分配器则是根据数据的大小,在堆内存找到合适大小的空区域存放,把它标记为已使用,并返回一个表示该位置地址的指针。该指针存储在栈上,当需要访问具体的数据时,必须先访问指针,然后通过指针找到堆上的位置,从而访问数据。这个过程可以用下图表示: -![注释](.././assets/4.png) +![注释](../assets/4.png)