RUST 图解 第 3 章:通用编程概念(Common Programming Concepts)

第 3 章:通用编程概念(Common Programming Concepts)

章节概要

本章涵盖变量与可变性、标量与复合数据类型、函数定义、注释规范以及控制流(if/loop/while/for)等通用编程概念。

本章图解

目录

  • [3.1 变量与可变性(Variables and Mutability)](#3.1 变量与可变性(Variables and Mutability))
  • [3.2 数据类型(Data Types)](#3.2 数据类型(Data Types))
  • [3.3 函数(Functions)](#3.3 函数(Functions))
  • [3.4 注释(Comments)](#3.4 注释(Comments))
  • [3.5 控制流(Control Flow)](#3.5 控制流(Control Flow))

正文内容

Concepts)

本章涵盖了⼏乎在所有现代编程语⾔中都会出现的概念,以及它们在 Rust 中的具体⼯作⽅式。虽然这些概念本身

并⾮ Rust 所独有,但我们将⽴⾜于 Rust 的语境来讨论它们,并阐述围绕它们的使⽤惯例。

具体来说,本章将探讨:

  • 变量与可变性(Variables and Mutability)
  • 数据类型(Data Types)
  • 函数(Functions)
  • 注释(Comments)
  • 控制流(Control Flow)
    关键字(Keywords)
    与其他语⾔类似,Rust 拥有保留给语⾔⾃身使⽤的关键字集合(例如 let、fn、mut 等)。你不能将这些保留字⽤
    作变量名或函数名。

变量与可变性(Variables and Mutability)

正如在第 2 章提到的,在 Rust 中,变量默认是不可变的(immutable)。这是 Rust 给予你的众多提示之⼀,引

导你写出能充分利⽤ Rust 提供的安全性与简便并发优势的代码。当然,你依然可以选择将变量声明为可变的。

当⼀个变量是不可变的时,⼀旦⼀个值绑定到⼀个名字上,你就不能再修改该值。

为了直观体会这⼀点,使⽤ Cargo 新建⼀个名为 variables 的项⽬:

rust 复制代码
cargo new variables BASH
cd variables

将 src/main.rs 的内容替换为以下代码(这段代码⽬前⽆法通过编译):

rust 复制代码
// src/main.rs RUST
fn main() {
let x = 5;
println!("The value of x is: {x}");
x = 6;


println!("The value of x is: {x}");
}

运⾏ cargo run,编译器会输出不可变错误信息:

rust 复制代码
cargo run PLAINTEXT

Compiling variables v0.1.0 (file:///projects/variables)

errorE0384: cannot assign twice to immutable variable x

--> src/main.rs:4:5

|

rust 复制代码
2 | let x = 5;

| - first assignment to x

rust 复制代码
3 | println!("The value of x is: {x}");
4 | x = 6;

| ^^^^^ cannot assign twice to immutable variable

help: consider making this binding mutable

|

rust 复制代码
2 | let mut x = 5;

| +++

这个例⼦展示了编译器如何协助你发现程序中的隐患。错误信息明确指出:不能对不可变变量 x 进⾏⼆次赋值。在

Rust 中,获得这类编译期错误⾄关重要,因为"意外修改本以为不会变的值"是许多隐蔽 Bug 的根源。Rust 编译器

保证:当你声明⼀个值不会变时,它就绝对不会改变,因此你⽆需⾃⼰在脑海中追踪它的状态变化。

但在某些场景下,可变性可以让代码编写更便利。只需在变量名前加上 mut 关键字即可将其声明为可变变量:

rust 复制代码
// src/main.rs RUST
fn main() {
let mut x = 5;
println!("The value of x is: {x}");
x = 6;
println!("The value of x is: {x}");
}

运⾏后成功输出:

The value of x is: 5 PLAINTEXT

The value of x is: 6

加上 mut 还向代码未来的阅读者清晰传达了意图:代码的其他部分将会改变这个变量的值。

常量(Declaring Constants)

类似于不可变变量,常量(constants)也是绑定到名称上且不允许修改的值。但常量与不可变变量有⼏点核⼼区

别:

  1. 常量不能使⽤ mut:常量不仅默认不可变,它们永远不可变。

  2. 声明⽅式与类型标注:声明常量使⽤ const 关键字⽽⾮ let,并且必须显式标注类型。

  3. 作⽤域灵活:常量可以在任何作⽤域中声明,包括全局作⽤域,这使得它们⾮常适合在代码的多处共享使

    ⽤。

  4. 编译期求值:常量只能被设置为常量表达式(constant expression),⽽不能是只能在运⾏时计算得出的

    值。

    常量示例:

rust 复制代码
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3; RUST

Rust 约定常量的命名规范为全⼤写字⺟,单词之间使⽤下划线隔开。编译器可以在编译期直接计算表达式 60 * 60

rust 复制代码
* 3 的结果(即 10800),这样书写既⽅便⼈类理解,也便于后期维护。常量在程序运⾏的整个⽣命周期内在其声

明的作⽤域中均有效。

变量遮蔽(Shadowing)

在第 2 章中你已经⻅识过:你可以声明⼀个与之前变量同名的新变量。Rustaceans 称之为第⼀个变量被第⼆个变

量遮蔽(shadowed)了。编译器在遇到该变量名时,看到的将是第⼆个新变量,直到它⾃身被再次遮蔽或其所在

的作⽤域结束:

rust 复制代码
// src/main.rs RUST
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {x}");
}
println!("The value of x is: {x}");
}

运⾏后输出:

The value of x in the inner scope is: 12 PLAINTEXT

The value of x is: 6

在内部花括号创建的作⽤域中,第三个 let 语句再次遮蔽了 x,将其值变为 12。离开内部作⽤域后,内部的遮蔽结

束,外部的 x 恢复为 6。

遮蔽(Shadowing)与可变变量(mut)的区别

  1. 重新保持不可变:遮蔽机制通过重复使⽤ let 关键字创建了⼀个全新的变量。我们可以对⼀个值进⾏⼏次变
    换计算,但在这些变换结束后,新变量依然保持不可变属性;如果我们忘记写 let ⽽直接给它赋值,编译器就
    会报错保护我们。
  2. 可以改变变量类型:因为遮蔽实际上是创建了新变量,所以新变量可以拥有与旧变量不同的数据类型:
rust 复制代码
let spaces = " "; // 字符串类型(&str) RUST
let spaces = spaces.len(); // 数字类型(usize)

如果试图⽤ mut 来实现这⼀点,则会报错:

rust 复制代码
let mut spaces = " "; RUST

spaces = spaces.len(); // 编译报错!⽆法修改变量本身的类型

数据类型(Data Types)

Rust 中的每⼀个值都有其特定的数据类型。Rust 是⼀⻔静态类型语⾔(statically typed language),这意味着

它必须在编译期获知所有变量的类型。

通常,编译器能够根据值及其使⽤上下⽂⾃动推断类型。但在存在多种可能类型时(例如从字符串使⽤ .parse()

转换为数字),必须显式给出类型注解:

rust 复制代码
let guess: u32 = "42".parse().expect("Not a number!"); RUST

如果省略 : u32,Rust 将⽆法确定解析为何种类型,编译报错。

Rust 的数据类型主要分为两⼤⼦集:标量类型(Scalar) 和 复合类型(Compound)。

标量类型(Scalar Types)

标量类型代表单⼀的值。Rust 有 4 种主要的标量类型:整数、浮点数、布尔值 和 字符。

  1. 整数类型(Integer Types)
    整数是没有⼩数部分的数字。每个类型都有显式的⼤⼩,分为有符号(以 i 开头)和⽆符号(以 u 开头):
    ⻓度 有符号(Signed) ⽆符号(Unsigned)
    8-bit i8 u8
    16-bit i16 u16
    32-bit i32(默认类型) u32
    64-bit i64 u64
    128-bit i128 u128
    视系统架构⽽定 isize usize
  • 有符号类型采⽤⼆进制补码(two's complement)表示,存储范围为 -(2^(n-1)) 到 2^(n-1) - 1。

  • ⽆符号类型存储范围为 0 到 2^n - 1。

  • isize 和 usize 的⼤⼩取决于⽬标运⾏平台的架构:在 64 位系统上是 64 位,在 32 位系统上是 32 位。它

    们的主要使⽤场景是对集合类型进⾏索引。

  • 默认整数类型:Rust 的整型默认是 i32,它通常速度最快,即使在 64 位系统上也表现优异。

    整数字⾯量书写⽅式:

  • ⼗进制:98_222(允许下划线 _ 作为视觉分隔符)

  • ⼗六进制:0xff

  • ⼋进制:0o77

  • ⼆进制:0b1111_0000

  • 字节(仅限 u8):b'A'

  • 字⾯量还⽀持类型后缀,例如 57u8。

    整数溢出(Integer Overflow)

    假设⼀个 u8 变量(范围 0 到 255)被赋予 256:

  • 在 Debug 模式 下编译时,Rust 包含溢出检查;⼀旦发⽣溢出,程序将在运⾏时 panic。

  • 在 Release 模式(--release)下编译时,Rust 不包含导致 panic 的溢出检查。相反,它执⾏⼆进制补码回

    绕(wrapping):256 变为 0,257 变为 1。依赖溢出回绕⾏为被视为⼀种错误。

  • 若要显式处理可能的溢出,可以使⽤标准库提供的特定⽅法:wrapping_(回绕)、checked_ (发⽣溢出

    返回 None)、overflowing_(返回结果及指示是否溢出的布尔值)和 saturating_ (饱和在最⼤/最⼩

    值)。

  1. 浮点数类型(Floating-Point Types)
    Rust 拥有两种浮点数原⽣类型,均遵循 IEEE-754 标准:
  • f32(32 位单精度)
  • f64(64 位双精度,默认类型,因为在现代 CPU 上它的速度与 f32 相当,但精度更⾼)
    所有的浮点类型都是有符号的。
rust 复制代码
let x = 2.0; // f64 RUST
let y: f32 = 3.0; // f32

数值运算(Numeric Operations)

Rust ⽀持基本的四则数学运算和取余:+、-、*、/、%。

  • 整数除法会向零截断(truncate toward zero)到最接近的整数(例如 -5 / 3 的结果是 -1)。
  1. 布尔类型(The Boolean Type)
    布尔类型⽤ bool 表示,⼤⼩为 1 个字节,只有两个可能的值:true 和 false。它主要⽤于条件控制流(如 if 表
    达式)。
rust 复制代码
let t = true; RUST
let f: bool = false; // 带有显式类型注解
  1. 字符类型(The Character Type)
    字符类型⽤ char 表示,使⽤单引号声明(字符串字⾯量使⽤双引号):
rust 复制代码
let c = 'z'; RUST
let z: char = 'ℤ';
let heart_eyed_cat = '😻';

Rust 的 char 类型⼤⼩为 4 个字节,表示⼀个 Unicode 标量值(Unicode Scalar Value)。它可以表示远多于

ASCII 的字符,包括拼⾳重⾳字⺟、中⽂、⽇⽂、韩⽂字符、emoji 表情符号以及零宽空格等。其取值范围从

U+0000 到 U+D7FF,以及 U+E000 到 U+10FFFF。

复合类型(Compound Types)

复合类型可以将多个值组合为⼀个类型。Rust 原⽣提供了两种基础复合类型:元组(Tuple) 和 数组(Array)。

  1. 元组类型(The Tuple Type)
    元组是将多个具有不同类型的值组合为⼀个复合类型的通⽤⽅式。元组具有固定⻓度:⼀旦声明,其⼤⼩不能增⻓
    或缩减。
    元组使⽤⼩括号包裹逗号分隔的值来创建:
rust 复制代码
let tup: (i32, f64, u8) = (500, 6.4, 1); RUST

提取元组中的值有两种⽅式:

  • 模式匹配解构(Destructuring):
rust 复制代码
let tup = (500, 6.4, 1); RUST
let (x, y, z) = tup;

println!("The value of y is: {y}"); // 输出 6.4

  • 点号索引访问(Dot notation):使⽤ . 后跟索引值(索引从 0 开始):
rust 复制代码
let five_hundred = tup.0; RUST
let six_point_four = tup.1;
let one = tup.2;

单元类型(Unit Type):没有任何值的元组有⼀个特殊名称叫 unit(单元类型),其值和类型均写作 ()。它表示

空值或空的返回类型。如果表达式没有返回其他任何值,它将隐式返回单元值 ()。

  1. 数组类型(The Array Type)

数组也是多个值的集合,但与元组不同:

  • 数组中的每⼀个元素必须是相同的类型。
  • Rust 中的数组同样具有固定⻓度。
    数组的值写在中括号内:
rust 复制代码
let a = [1, 2, 3, 4, 5]; RUST
  • 使⽤场景:当希望数据被分配在栈(stack)上⽽不是堆(heap)上,或者希望确保元素数量始终固定时,
    数组⾮常有⽤(例如⼀年中 12 个⽉份的名称)。
  • 与 Vector 的区别:标准库提供的 Vector(动态数组)允许在堆上动态伸缩;如果不确定该⽤数组还是
    Vector,通常应该选择 Vector(将在第 8 章详述)。
    数组类型注解与初始化语法:
  • 类型写法为 类型; ⻓度,例如 let a: i32; 5 = 1, 2, 3, 4, 5;。
  • 初始化包含相同初始值的数组:let a = 3; 5;(等同于 let a = 3, 3, 3, 3, 3;)。
    数组元素访问与越界检查:使⽤中括号及索引访问,例如 a0。
rust 复制代码
let a = [1, 2, 3, 4, 5]; RUST
let first = a[0];
let second = a[1];

如果尝试访问越界的索引(例如 a10),Rust 会在运⾏时 panic:

index out of bounds: the len is 5 but the index is 10 PLAINTEXT

这是 Rust 内存安全原则 的体现。在许多底层语⾔(如 C)中,越界访问不会被检查,导致⾮法读取未分配或属于

其他数据的内存(缓冲区越界读 / buffer overread)。Rust 通过在运⾏时进⾏边界检查并⽴即终⽌程序来避免这

种内存安全漏洞。

函数(Functions)

在 Rust 中,函数⽆处不在。使⽤ fn 关键字声明函数。

Rust 代码约定使⽤ 蛇形命名法(snake case) 作为函数与变量名的规范⻛格:所有字⺟均⼩写,单词之间⽤下划

线分隔。

rust 复制代码
// src/main.rs RUST
fn main() {


println!("Hello, world!");
another_function();
}
fn another_function() {
println!("Another function.");
}

Rust 不在乎你在哪⾥定义函数,只要在调⽤者能看得⻅的作⽤域内定义了它即可(定义在 main 之前或之后都可

以)。

函数参数(Parameters)

函数可以定义包含参数。在函数签名中,必须显式声明每个参数的类型。这是 Rust 设计中的刻意决定:强制参数

类型注解意味着编译器⼏乎⽆需在其他地⽅推测函数意图,并且能在发⽣不匹配时提供极其精准的错误提示。

多个参数之间使⽤逗号隔开:

rust 复制代码
fn main() { RUST
print_labeled_measurement(5, 'h');
}
fn print_labeled_measurement(value: i32, unit_label: char) {
println!("The measurement is: {value}{unit_label}");
}

语句与表达式(Statements and Expressions)

Rust 是⼀⻔基于表达式(expression-based)的语⾔,这是⼀个极其关键的概念区别:

  • 语句(Statements):是执⾏某种动作并不返回值的指令。
  • 表达式(Expressions):进⾏计算并产⽣⼀个结果值。
  • 变量绑定 let y = 6; 是⼀条语句。因为语句不返回值,所以不能将 let 语句赋值给另⼀个变量(在 C 或
    Ruby 中可以写 x = y = 6,但在 Rust 中不⾏):
rust 复制代码
let x = (let y = 6); // 编译报错! RUST
  • 表达式会计算出⼀个值。5 + 6 是⼀个求值为 11 的表达式。函数调⽤是表达式,宏调⽤是表达式,花括号创
    建的代码块 {} 也是表达式:
rust 复制代码
let y = { RUST
let x = 3;

x + 1 // 注意:结尾没有分号!

rust 复制代码
};

println!("The value of y is: {y}"); // y 的值是 4

注意:表达式末尾没有分号! 如果你在表达式末尾加上了分号,它就变成了语句,语句不会返回值。

具有返回值的函数(Functions with Return Values)

函数可以向调⽤者返回值。在函数签名中,我们在箭头 -> 后声明返回值的类型。

在 Rust 中,函数的返回值等同于其函数体代码块中最后⼀个表达式的值。虽然可以使⽤ return 关键字显式提前

返回,但⼤多数惯⽤的 Rust 代码都是隐式返回最后⼀个表达式:

rust 复制代码
fn five() -> i32 { RUST

5 // 这是⼀个表达式,作为返回值;不要加分号!

rust 复制代码
}
fn main() {
let x = five();

println!("The value of x is: {x}"); // 输出 5

rust 复制代码
}

再看⼀个示例:

rust 复制代码
fn plus_one(x: i32) -> i32 { RUST

x + 1

rust 复制代码
}

如果你在 x + 1 后⾯不⼩⼼加了⼀个分号 ;:

rust 复制代码
fn plus_one(x: i32) -> i32 { RUST

x + 1; // 变成了⼀条语句!

rust 复制代码
}

编译器会抛出类型不匹配错误:

errorE0308: mismatched types PLAINTEXT

--> src/main.rs:7:24

|

rust 复制代码
7 | fn plus_one(x: i32) -> i32 {

| -------- ^^^ expected i32, found ()

| |

| implicitly returns () as its body has no tail or return expression

rust 复制代码
8 | x + 1;

| - help: remove this semicolon to return this value

因为语句不产⽣值,代码块隐式返回了单元类型 (),与函数签名承诺的 i32 发⽣冲突,编译器会贴⼼地建议你移

除分号。

注释(Comments)

在 Rust 中,惯⽤的单⾏注释以两条正斜杠 // 开始,并⼀直持续到⾏尾:

rust 复制代码
// 这是⼀个独⽴的注释⾏ RUST
let lucky_number = 7; // 也可以位于代码⾏末尾

对于跨越多⾏的注释,每⾏均以 // 开头:

rust 复制代码
// 这是⼀段较为复杂的逻辑, RUST
// 我们通过多⾏注释来详细解释
// 具体的实现思路。

此外,Rust 还提供⽂档注释(以 /// 开头),这将在第 14 章详细讨论。

控制流(Control Flow)

控制代码执⾏流向的最常⻅结构是 if 表达式 和 循环(loops)。

  1. if 表达式
rust 复制代码
if 表达式允许根据条件分⽀执⾏代码:
// src/main.rs RUST
fn main() {
let number = 3;
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
}
  • 条件必须是 bool 类型:与 JavaScript 或 Python 等语⾔不同,Rust 不会⾃动尝试将⾮布尔类型转换为布
    尔值。如果写 if number {,编译器会直接报错 expected bool, found integer。必须显式提供布尔条件,例
    如 if number != 0 {。
    使⽤ else if 处理多重条件
rust 复制代码
fn main() { RUST
let number = 6;


if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
}

程序按顺序检查各个条件,⼀旦发现第⼀个为 true 的分⽀,就会执⾏对应分⽀的代码并跳出判断,不会再去检查

后续的分⽀(即使 6 同样能被 2 整除)。如果 else if 过多,通常应重构为第 6 章的 match 结构。

在 let 语句中使⽤ if

因为 if 是⼀个表达式,所以可以直接将其放在 let 语句等号右侧来为变量赋值:

rust 复制代码
fn main() { RUST
let condition = true;
let number = if condition { 5 } else { 6 };

println!("The value of number is: {number}"); // 输出 5

rust 复制代码
}
• 所有分⽀的返回类型必须相同:变量必须有唯⼀定义的类型。如果写 let number = if condition { 5 }

else { "six" };,编译将会失败,因为 if 臂和 else 臂的返回类型不兼容(integer 与 &str)。

  1. 循环(Repetition with Loops)

Rust 提供了 3 种循环结构:loop、while 和 for。

rust 复制代码
loop 循环
loop 关键字指示 Rust ⼀遍⼜⼀遍地反复执⾏代码块,直到遇到中断或显式终⽌:
fn main() { RUST
loop {
println!("again!");
}
}

终端可以通过快捷键 Ctrl-C 终⽌死循环。代码中可以通过 break 退出循环,或通过 continue 跳过当前迭代直

接进⼊下⼀次循环。

从循环中返回值

rust 复制代码
loop 常⽤于需要重试可能失败的操作(如轮询线程状态)。你可以将需要传递给外部的结果值放在 break 之后返

回:

rust 复制代码
fn main() { RUST
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // 返回 20
}
};

println!("The result is {result}"); // 输出 20

rust 复制代码
}

循环标签(Loop Labels)消除多层嵌套歧义

如果有嵌套的多层循环,break 和 continue 默认只作⽤于最内层循环。你可以在循环前指定以单引号开头的循环

标签(loop label),并结合 break/continue 精确跳出指定的外层循环:

rust 复制代码
fn main() { RUST
let mut count = 0;
'counting_up: loop {
println!("count = {count}");
let mut remaining = 10;
loop {
println!("remaining = {remaining}");
if remaining == 9 {

break; // 仅退出内层循环

rust 复制代码
}
if count == 2 {
break 'counting_up; // 退出外层 labeled 循环
}
remaining -= 1;
}
count += 1;
}
println!("End count = {count}");
}
while 条件循环

当需要在循环内判断条件时,while 循环是内置的语法糖,避免⼿动组合 loop、if、else 和 break:

rust 复制代码
fn main() { RUST
let mut number = 3;
while number != 0 {


println!("{number}!");
number -= 1;
}
println!("LIFTOFF!!!");
}
for 循环遍历集合

虽然可以使⽤ while 结合下标索引来遍历数组或集合,但这种做法容易出错(例如索引写错导致越界 panic),且

运⾏时每次迭代都要做越界检查因此较慢。

Rust 中更安全、简洁、⾼效且最常⽤的⽅式是 for 循环:

rust 复制代码
fn main() { RUST
let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {element}");
}
}

使⽤ for 循环彻底杜绝了越界或遗漏元素的可能,同时编译⽣成的机器码效率更⾼。

如果要实现指定次数的循环(例如倒计时),可以配合标准库的 Range(范围)及其 .rev()(反转)⽅法:

rust 复制代码
fn main() { RUST
for number in (1..4).rev() {
println!("{number}!");
}
println!("LIFTOFF!!!");
}

(1...4) ⽣成 1、2、3(前闭后开区间),.rev() 将其倒转为 3、2、1,代码清晰且优雅。

本章⼩结(Summary)

本章内容⾮常充实!你系统掌握了:

  1. 变量与可变性:默认不可变、mut 声明可变、const 常量以及通过 shadowing 优雅转换数据。
  2. 基本数据类型:
  • 标量类型:整数(i32、溢出机制)、浮点数(f64)、布尔型(bool)、字符(char,4 字节 Unicode)。
  • 复合类型:固定⻓度与异构的元组(tuple)、固定⻓度与同构的数组(array 及其越界保护)。
  1. 函数与语义:参数强类型注解,深刻理解语句(不返回值)与表达式(返回值)的核⼼差异,以及函数末尾

⽆分号的隐式返回特性。

  1. 控制流:强布尔类型的 if 表达式(可赋值给 let),以及 loop(可带返回值与标签)、while 和最惯⽤的
rust 复制代码
for 集合/区间遍历。

练习建议:尝试⾃⼰动⼿写⼏个⼩程序巩固这些知识:

  1. 摄⽒度与华⽒度温度互相转换。

  2. ⽣成第 n 个斐波那契数。

  3. 利⽤循环和重复特性打印圣诞颂歌《The Twelve Days of Christmas》的歌词。
    准备好后,我们将在第 4 章迈⼊ Rust 独⼀⽆⼆的核⼼基⽯------所有权(Ownership)机制!
    FF!!!");
    }

    (1..4) ⽣成 1、2、3(前闭后开区间),.rev() 将其倒转为 3、2、1,代码清晰且优雅。
    本章⼩结(Summary)
    本章内容⾮常充实!你系统掌握了:

    1. 变量与可变性:默认不可变、mut 声明可变、const 常量以及通过 shadowing 优雅转换数据。
    2. 基本数据类型:
    • 标量类型:整数(i32、溢出机制)、浮点数(f64)、布尔型(bool)、字符(char,4 字节 Unicode)。
    • 复合类型:固定⻓度与异构的元组(tuple)、固定⻓度与同构的数组(array 及其越界保护)。
    1. 函数与语义:参数强类型注解,深刻理解语句(不返回值)与表达式(返回值)的核⼼差异,以及函数末尾

    ⽆分号的隐式返回特性。
    4. 控制流:强布尔类型的 if 表达式(可赋值给 let),以及 loop(可带返回值与标签)、while 和最惯⽤的

    rust 复制代码
    for 集合/区间遍历。

练习建议:尝试⾃⼰动⼿写⼏个⼩程序巩固这些知识:

  1. 摄⽒度与华⽒度温度互相转换。
  2. ⽣成第 n 个斐波那契数。
  3. 利⽤循环和重复特性打印圣诞颂歌《The Twelve Days of Christmas》的歌词。
    准备好后,我们将在第 4 章迈⼊ Rust 独⼀⽆⼆的核⼼基⽯------所有权(Ownership)机制!
相关推荐
夏幻灵1 小时前
每日一题:LeetCode 165:比较版本号
算法·leetcode·职场和发展
道尔柯南1 小时前
C++ 面向对象编程入门:类和对象(上)
开发语言·c++·算法
楠楠子呀2 小时前
英语、西语、阿语客户各开一个口:多语言获客的分流方案
开发语言·javascript·ecmascript·跨境电商·whatsapp·营销工具
Navigator_Z2 小时前
LeetCode //C - 1288. Remove Covered Intervals
c语言·算法·leetcode
tachibana22 小时前
使用for range 的时候,它的地址会发生变化吗?
开发语言·后端·golang·go·语法
码爸2 小时前
决策树介绍与示例
python·算法·机器学习
动词ing2 小时前
【题目练习】字符串相乘
算法
临床数据科学和人工智能兴趣组2 小时前
正则表达式的基础语法的基本符号
开发语言·人工智能·python·正则表达式·r语言·r语言-4.2.1·workbudyy
王中阳Go2 小时前
Go 后端转 AI:非科班怎么补?一张 3 列路线表(可保存)
开发语言·人工智能·后端·python·golang·大语言模型