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 独有的概念。
-
所有权(Ownership): Rust 的所有权系统是它区别于其他语言的独特特性。所有权规则保证了 Rust 程序的内存安全,无需垃圾收集器。每个值在 Rust 中都有一个被称为其所有者的变量,且一次只能有一个所有者。
-
借用(Borrowing): Rust 通过引用允许你访问数据而不取得其所有权。引用分为两类:不可变引用(
&T)和可变引用(&mut T),这与变量的可变性相对应。 -
生命周期(Lifetimes): 生命周期是 Rust 的一个重要部分,它们确保了引用始终有效。生命周期在函数签名和结构体定义中显式标注,帮助 Rust 编译器保证数据的有效性。
-
错误处理: Rust 提供了
Result<T, E>和Option<T>枚举来处理可能的错误。Result用于可能会出错的操作,而Option用于可能为空的值。 -
模块系统(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的结构体,带有两个字段width和height,都是u32类型(无符号 32 位整数)。let rect = Rectangle { ... }: 创建一个Rectangle实例。area(&rect): 调用area函数并传入rect的引用。在 Rust 中,使用&表示创建一个引用,它允许你使用值而不获取其所有权。fn area(rectangle: &Rectangle) -> u32 { ... }: 定义一个函数area,它接受Rectangle的一个不可变引用并返回一个u32类型的值,即矩形的面积。
这些代码示例不仅展示了 Rust 代码的基本结构,还展示了如何使用 Rust 的一些核心特性,如宏、模式匹配、结构体和函数。这些是构建任何 Rust 应用程序的基石。通过理解和运用这些基本概念,你将能够开始使用 Rust 语言,并逐步掌握更复杂的概念和技术。