Rust 中的变量默认是不可变的, 要定义可变化的变量, 需要添加 mut 显式说明
// 变量和可变性
let mut x = 1;
// 常量, 总是不可变的, 且必须有类型注释, 常量可以在任何作用域中声明
const SECONDS: u32 = 60 * 60;
// 变量覆盖, 新的 x 将变为 6
let x = 5;
let x = x + 1;
// 这将报错, 指定类型无法解析, 超过范围也将报错比如 "256"
let guess: u8 = "-1".parse().expect("Number Error!");
标量类型表示单个值, Rust有四种主要的标量类型: 整数、浮点数、布尔值和字符。
// i8 ~ i128, isize 将随体系结构而变化, 默认类型 i32
// 表现形式, 可通过 _ 来分隔
let x = 98_222;
let x = 0xff;
let x = 0o77;
let x = 0b1111_0000;
let x = b'A'; // 仅用于 u8 类型, 这时 x 将自动为 u8
let x = b'A' as u32; // 将 u8 转换为 u32
let x = 57u8; // 指定为 u8 类型
整数溢出在 debug 模式时会抛出错误, 但在 release 模式则会取溢出后某个值, 可显式处理要溢出的可能性:
let x: u8 = 255;
let y = x.checked_add(2);
if y.is_none() {
// 溢出了
} else {
// 没有溢出
}
f32 和 f64 (默认)
整数与浮点同时存在的表达式中,Rust 默认不会自动转化,需显式强制转换
let x = 5;
let x = x as f32 * 3.14;
true
false
char
Rust 的 char 类型大小为 4 个字节, 表示 Unicode 标量值
这使得可以定义一个 char 保存一个 emoj 表情 let emoj = '';
复合类型可以将多个值组合到一个类型中。Rust有两个 原始复合类型:元组和数组
是一种将多个值分组在一起的通用方法, 将多种类型合并为一个复合类型。元组有一个固定的长度:一次声明,他们不能增长或缩小的大小
let tup = (500, 6.4, 1);
// _ 忽略该元组元素
let (x, y, _) = tup;
// 可通过 '.' 符号访问元组元素
let one = tup.0;
println!("y: {y}, one: {one}");
// 空元组
let x = ();
另一种拥有多个值的集合的方法是使用数组。不像元组,数组的每个元素必须具有相同的类型。
数组是一个已知的、固定大小的内存块,在栈上分配, 因此数组必须长度必须是固定的。
let a = [1, 2, 3, 4, 5];
// 类型注释, 在括号中表示类型和数组大小
let a: [u8; 5] = [1, 2, 3, 4, 5];
// 赋予初值, 在括号中表示赋予每个元素的初值和数组大小
let a = [0; 5];
// 当访问越界,无论 debug 还是 release,Rust 程序将退出并显示错误消息
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
let index: usize = input.trim().parse().unwrap();
let x = a[index];
Rust 对语句和表达式有严格的区分:
这点和 C 不同, 例如 x = y = 0
在 C 是成立的, 但是 Rust 会认为 y = 0
是一个语句, 无法将其赋值给 x
除了计算, 调用函数, 调用宏等表达式。创建的新范围块大括号也是一个表达式:
// 注意: 若在末尾添加分号,它将变成一个语句,不会返回任何值
let y = { let x = 3; x + 1 };
函数定义本身是一个语句
fn main() {
let c = add(1, 2);
println!("{c}");
}
// 函数定义位置可在调用后面, 函数必须声明函数参数类型
fn add(a: i32, b: i32) -> i32 {
// return a + b; 可简写为如下形式
a + b
}
let number = 3;
// Rust 不会将非布尔自动转布尔, 须明确并始终提供 if 以布尔值作为条件
if number != 0 {
println!("number was something other than zero");
}
// 因为 if 是一个表达式, 我们可以将值传给 let 变量
let number = if condition { 5 } else { 6 };
// 编译错误, if 作为表达式赋值时, if 每个分支产出的值必须具有相同的类型
let number = if condition { 5 } else { "six" };
Rust 具有三种循环:loop、while 和 for
// break 可以用于从循环表达式中返回一个值
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
// 循环嵌套中, 可以 break 或 continue 指定标签用于从内层循环中跳出
'counting_up: loop {
loop {
break 'counting_up;
}
}
// 条件循环
let mut number = 3;
while number != 0 {
println!("{number}!");
number -= 1;
}
// for 循环, i 取 0, 1, 2 表达式 0..3 返回可迭代的 Range<> 类型
for i in 0..3 {
println!("{i}");
}
// i 取值变成 0, 1, 2, 3
for i in 0..=3 {
println!("{i}");
}
// Range<> 类型包含多种方法, step_by() 指定步进长度, rev() 将序列反转
for i in (0..3).rev() {
println!("{i}");
}
// 数组本身就是可迭代的
let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {element}");
}