Home
Perfecto的头像

Perfecto

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 = 4

1.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 提供三种循环:loopwhilefor

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的根部,
//! 用于描述整个模块或crate

1.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())
}
Rust语法学习