Chapter3 Common Programming Concepts
Variables and Mutability
默认情况下, 定义的变量时不可变的. 如果要定义可变变量, 则使用 mut
.
常量实际时值绑定到一个名字, 并且不允许中编译后修改, 使用 const
定义.
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 *3;
Rust 编译器能够对有限的操作进行值计算, 详见官方文档.
常量的生命期是整个 APP 运行期间.
关于变量的名 字覆盖, 可以在相同/不同作用域下覆盖变量, 但不能进行改变类型的覆盖.
// !! 这种改变类型的覆盖是不允许的.
let mut spaces = " ";
spaces = spaces.len();
Data Types
Rust 中每个值都有确定的类型, 有两大类数据类型:
- 原子类型(Scalar)
- 组合类型(Compound)
Scalar Types
有如下四类原子类型:
- 整型(Integers):
i8/u8/i16/u16/i32/u32/i64/u64/i128/u128/isize/usize
- Integer 常量写法:
98_222
(Decimal),0xff
(Hex),0o77
(Octal),0b111_000
(Binary),b'A'
(Byte u8 only) - Rust 在 Release 编译时不会进行整型溢出检测, 意味着当溢出发生时, Rust 会进行归位(比如 u8 在 256 时溢出后会变成 0, 257 时溢出变为 1, 以此类推), 而在 Debug 编译时溢出会引起 panic.
- Rust 在整数运算时的行为时整除.
- Integer 常量写法:
- 浮点类型(Floating-Point Numbers):
f32/f64
, 类型推断时默认浮点类型时f64
. - 布尔类型(Booleans):
true/false
- 字符型(Characters):
'a'
,'A'
等, 字符型是 UTF-8 编码的, 即它每一个都是 4 字节大小.- Unicode 字符取值范围是: [U+0000, U+D7FF] 以及 [U+E000, U+10FFFF].
Compound Types
组合类型时一系列值的集合, Rust 有两种基本组合类型:
- Tuple
- Array
Tuple Type
let tup: (i32, f64, u8) = (5000, 6.4, 1);
let (x, y, z) = tup; // destruction
let e = tup.0;
Array Type
fn main() {
let a1 = [1,2, 3, 4, 5];
let months = ["apple", "bird", "cat", "dog"];
let a2: [u8; 5] = [6, 7, 8, 9, 10]
let a3 = [3; 5]; // [5, 5, 5]
let first_elem = a1[0];
}
Rust 会进行数组越界检查.
函数
fn add(a: u8, b: u8) -> u8 {
a + b
}
Expressions
fn main() {
let y = {
let x = 3;
x + 1
} // y equals 4
}
Control Flow
fn main() {
let num = 3;
if num > 5 {
println!("condition was false");
} else {
println!("condition was true");
}
// if 可以用在 let 表达式右侧, 类似三元操作符 ?: 的作用
let num = if xxx { 5 } else { 6 };
}
循环
可以使用 loop
进行无限循环.
fn main() {
let mut counter = 0;
// 可以从循环中获取结果值
let result = loop { // result equals 10
counter += 1;
if counter > 10 {
break counter;
}
};
while counter != 0 {
counter -= 1;
}
let a1 = [1, 2, 3, 4, 5];
for elem in a1 { // 1, 2, 3, 4, 5
// ...
}
for num in (1..4).rev() {// 3, 2, 1
// ...
}
loop { // infinite loop
println!("hello");
}
}
可以为 loop 设置标签, 这样比较方便地就可以 break 对应循环(嵌套循环的情况下):
fn main() {
let mut count = 0;
'counting_up: loop {
println!("count = {count}");
let mut remaining = 10;
loop {
println!("remaining = {remaining}");
if remaining == 9 {
break;
}
if count == 2 {
break 'counting_up;
}
remaining -= 1;
}
count += 1;
}
println!("End count = {count}");
}
使用 while
进行有条件的循环:
fn main() {
let mut number = 3;
while number != 0 {
println!("{number}!");
number -= 1;
}
println!("LIFTOFF!!!");
}
使用 for
循环遍历集合:
fn main() {
for number in (1..4).rev() {
println!("{number}!");
}
let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {element}");
}
}