Rust语法速览

在探索编程语言的海洋中,Rust 以其独特的特性和安全保证脱颖而出。如果你正寻找一种兼具效率和可靠性的语言,那么 Rust 可能就是你的新挚友。这里,我们将一探 Rust 的基本语法,帮助你迈出学习之旅的第一步。

声明变量和常量

在 Rust 中,一切从变量开始:

let x = 5; // 这里我们声明了一个不可变的变量 x,赋值为整数 5
let mut y = 10; // 可变变量 y,你可以改变它的值
const Z: i32 = 15; // 常量 Z,它的值永远不变,类型明确为 32 位整数

Rust 的变量默认是不可变的。这是 Rust 强调安全性的一个例子——通过不可变性,它鼓励你写出更可预测的代码。

数据类型

Rust 提供了多种数据类型,以支持不同的用例和场景:

let number: i32 = 42; // 这是一个 32 位的有符号整数
let float: f64 = 3.14; // 这里我们有一个 64 位的浮点数
let character: char = 'a'; // Rust 的 char 类型是一个 Unicode 字符
let boolean: bool = true; // 布尔值,非真即假
let string: String = String::from("Hello, Rust!"); // 字符串类型,存储文本信息
let array: [i32; 3] = [1, 2, 3]; // 一个固定长度的整数数组
let vector: Vec<i32> = vec![4, 5, 6]; // 动态长度的向量,类似于其他语言的数组或列表

这些类型是 Rust 强类型系统的基石,确保在编译时就捕获类型错误。

控制流语句

控制流语句是编程的基本结构,Rust 在这方面也不例外:

if x > 0 {
    println!("x is positive");
} else if x < 0 {
    println!("x is negative");
} else {
    println!("x is zero");
}

let result = if y > 0 { "positive" } else { "negative" };

for i in 0..5 {
    println!("The value of i is: {}", i);
}

while y > 0 {
    println!("The value of y is: {}", y);
    y -= 1;
}

match number {
    1 => println!("One"),
    2 | 3 => println!("Two or Three"),
    _ => println!("Other"),
}

上述示例展示了条件判断、循环和模式匹配,是 Rust 控制逻辑的三大支柱。

函数定义和调用

函数是组织代码的强大工具。在 Rust 中,定义和使用函数也非常直接:

fn add(x: i32, y: i32) -> i32 {
    x + y
}

let sum = add(3, 4);
println!("The sum is: {}", sum);

通过定义 add 函数,我们展示了如何将代码组织成可重用的单元。

Rust 的独特概念

要开始编写 Rust 代码,除了上述基础,还需要理解一些 Rust 独有的概念。

  1. 所有权(Ownership): Rust 的所有权系统是它区别于其他语言的独特特性。所有权规则保证了 Rust 程序的内存安全,无需垃圾收集器。每个值在 Rust 中都有一个被称为其所有者的变量,且一次只能有一个所有者。

  2. 借用(Borrowing): Rust 通过引用允许你访问数据而不取得其所有权。引用分为两类:不可变引用(&T)和可变引用(&mut T),这与变量的可变性相对应。

  3. 生命周期(Lifetimes): 生命周期是 Rust 的一个重要部分,它们确保了引用始终有效。生命周期在函数签名和结构体定义中显式标注,帮助 Rust 编译器保证数据的有效性。

  4. 错误处理: Rust 提供了 Result<T, E>Option<T> 枚举来处理可能的错误。Result 用于可能会出错的操作,而 Option 用于可能为空的值。

  5. 模块系统(Modules): Rust 通过模块系统组织代码,可以在不同文件和命名空间中管理函数、结构体和其他项。

完整的代码示例

让我们通过一些实际的代码示例来加深理解。

示例 1: 打印 Hello World

fn main() {
    println!("Hello, world!");
}
  • fn main() { ... }: 这是 Rust 程序的入口点。每个可执行的 Rust 程序都有一个 main 函数。
  • println!("Hello, world!");: 这行代码调用了一个宏(注意 ! 符号),它打印文本到控制台。在双引号内的 "Hello, world!" 是被打印的字符串。这种简单的程序是大多数编程语言入门的传统,旨在展示基本的语法和程序结构。

示例 2: 猜数字游戏

use std::io; // 引入标准库的输入/输出(I/O)功能。
use rand::Rng; // 引入随机数生成器的特性。
use std::cmp::Ordering; // 引入用于比较的枚举。

fn main() {
    println!("Guess the number!");
    let secret_number = rand::thread_rng().gen_range(1..101); // 生成一个 1 到 100 之间的随机数。

    loop {
        println!("Please input your guess.");

        let mut guess = String::new(); // 创建一个可变的字符串来存储用户的输入。
        io::stdin().read_line(&mut guess).expect("Failed to read line"); // 读取用户输入。

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num, // 如果输入是一个有效的数字,继续。
            Err(_) => continue, // 如果输入无效,再次请求输入。
        };

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break; // 用户猜对了,退出循环。
            }
        }
    }
}
  • loop: 一个无限循环,直到明确使用 break 跳出循环。
  • String::new(): 创建一个新的空字符串。
  • io::stdin().read_line(&mut guess): 调用标准输入读取一行数据到 guess 字符串中。
  • match guess.trim().parse() { ... }: 尝试将输入的字符串转换为数字,并处理可能的错误。
  • match guess.cmp(&secret_number) { ... }: 比较猜测的数字和秘密数字,并给出相应的提示。

示例 3: 函数和结构体的使用

struct Rectangle { // 定义一个结构体,用于存储矩形的宽和高。
    width: u32,
    height: u32,
}

fn main() {
    let rect = Rectangle {
        width: 30,
        height: 50,
    }; // 创建一个 Rectangle 实例。

    println!(
        "The area of the rectangle is {} square pixels.",
        area(&rect)
    ); // 打印矩形的面积。
}

fn area(rectangle: &Rectangle) -> u32 { // 定义一个函数计算矩形的面积。
    rectangle.width * rectangle.height
}
  • struct Rectangle { ... }: 定义一个名为 Rectangle 的结构体,带有两个字段 widthheight,都是 u32 类型(无符号 32 位整数)。
  • let rect = Rectangle { ... }: 创建一个 Rectangle 实例。
  • area(&rect): 调用 area 函数并传入 rect 的引用。在 Rust 中,使用 & 表示创建一个引用,它允许你使用值而不获取其所有权。
  • fn area(rectangle: &Rectangle) -> u32 { ... }: 定义一个函数 area,它接受 Rectangle 的一个不可变引用并返回一个 u32 类型的值,即矩形的面积。

这些代码示例不仅展示了 Rust 代码的基本结构,还展示了如何使用 Rust 的一些核心特性,如宏、模式匹配、结构体和函数。这些是构建任何 Rust 应用程序的基石。通过理解和运用这些基本概念,你将能够开始使用 Rust 语言,并逐步掌握更复杂的概念和技术。