Rust 语法学习 - 基础语法
1.1 变量与可变性
let x = 5; // 不可变绑定
let mut y = 10; // 可变绑定
const MAX_POINTS: u32 = 100_000; // 常量- Rust 变量默认不可变,需要显式声明
mut使其可变 - 常量必须显式标注类型,命名惯例是全大写加下划线
- 可以使用
let关键字重新声明同名变量,这被称为”遮蔽”(Shadowing)
let x = 5;
let x = x + 1; // x 现在是 6
let x = x * 2; // x 现在是 12变量遮蔽与可变性的区别
- 使用
let创建的新变量可以改变类型,而mut不行 - 遮蔽实际上创建了一个新变量,只是复用了同样的名称
let spaces = " "; // 字符串类型
let spaces = spaces.len(); // 数值类型 - 有效
// 与之相对的:
let mut spaces = " ";
spaces = spaces.len(); // 类型不同 - 错误!1.2 数据类型
Rust 是静态类型语言,编译时必须知道所有变量的类型。编译器通常可以根据值和使用方式推断类型。
标量类型
整数类型
let a: i32 = -42; // 有符号整数
let b: u32 = 42; // 无符号整数
let c: i32 = 0xff; // 十六进制
let d: i32 = 0o77; // 八进制
let e: i32 = 0b1111_0000; // 二进制
let f: u8 = b'A'; // 字节(仅限u8)浮点类型
let x = 2.0; // f64 (默认)
let y: f32 = 3.0; // f32布尔类型
let t = true;
let f: bool = false;字符类型
let c = 'z';
let z = 'ℤ'; // Unicode字符
let heart_eyed_cat = '😻'; // Unicode表情复合类型
元组
// 元组
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup; // 解构
let five_hundred = tup.0; // 点号访问
// 单元元组
let unit = (); // 空元组,也称为单元类型数组
// 数组 - 固定长度,元素类型相同
let arr = [1, 2, 3, 4, 5];
let first = arr[0]; // 索引访问
let arr_type: [i32; 5] = [1, 2, 3, 4, 5]; // 显式类型
let arr_same = [3; 5]; // [3, 3, 3, 3, 3]注意:数组访问越界会导致运行时错误(panic),这与一些语言允许越界不同。
1.3 函数
fn add(x: i32, y: i32) -> i32 {
x + y // 无分号,作为返回值
}
fn print_hello() {
println!("Hello, world!");
}
// 具有复杂逻辑的函数
fn calculate_length(s: String) -> (String, usize) {
let length = s.len(); // 获取字符串长度
(s, length) // 返回元组,包含字符串和长度
}- 参数必须显式标注类型
- 返回值使用
->指定类型 - 最后一个表达式(没有分号)自动作为返回值,或用
return显式返回 - Rust 的函数和语句遵循”蛇形命名”(snake_case):小写字母加下划线
语句与表达式
Rust 是一种基于表达式的语言:
- 语句:执行操作但不返回值
- 表达式:计算并产生一个值
// 语句
let y = 6; // 没有返回值
// 表达式
let y = {
let x = 3;
x + 1 // 注意没有分号,这是一个表达式
}; // y = 41.4 控制流
if 表达式
let number = 6;
if number % 4 == 0 {
println!("divisible by 4");
} else if number % 3 == 0 {
println!("divisible by 3");
} else {
println!("not divisible by 3 or 4");
}
// if 是表达式,可以赋值
let condition = true;
let number = if condition { 5 } else { 6 };
// 分支返回值类型必须相同
let number = if condition { 5 } else { "six" }; // 错误!循环
Rust 提供三种循环:loop、while 和 for。
loop 循环
// loop 无限循环
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // 可以从loop返回值
}
};
// result = 20
// 循环标签:处理嵌套循环
'outer: loop {
println!("进入外层循环");
'inner: loop {
println!("进入内层循环");
// 这会中断内层循环
break;
// 这会中断外层循环
// break 'outer;
}
println!("内层循环后的外层循环");
break;
}while 条件循环
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("起飞!");for 循环
// 遍历数组
let arr = [10, 20, 30, 40, 50];
for element in arr {
println!("值是: {}", element);
}
// 范围循环
for number in 1..4 { // 不包含上限
println!("{}!", number); // 打印 1, 2, 3
}
for number in 1..=4 { // 包含上限
println!("{}!", number); // 打印 1, 2, 3, 4
}
// 反向范围
for number in (1..4).rev() {
println!("{}!", number); // 打印 3, 2, 1
}1.5 注释与文档
// 这是单行注释
/*
这是块注释,
可以跨越多行
*/
/// 这是文档注释,用于生成文档
/// # 例子
/// ```
/// let five = 5;
/// ```
fn documented_function() {
// 函数实现
}
//! 这种文档注释通常用在模块或crate的根部,
//! 用于描述整个模块或crate1.6 基本输入输出
// 输出
println!("Hello, world!"); // 带换行
print!("No newline here"); // 不带换行
// 格式化输出
println!("My name is {} and I'm {} years old", "Alice", 30);
println!("十进制: {}, 十六进制: {:x}, 二进制: {:b}", 10, 10, 10);
// 命名参数
println!("{name} is {age} years old", name="Bob", age=25);
// 调试格式
println!("调试输出: {:?}", (1, 2, "hello"));
println!("美化调试输出: {:#?}", vec![1, 2, 3]);
// 输入
use std::io;
fn read_input() -> io::Result<String> {
let mut input = String::new();
io::stdin().read_line(&mut input)?;
Ok(input.trim().to_string())
}