Rust 基础入门教程
Rust 是一门现代的系统编程语言,以其内存安全、并发性和高性能而著称。Rust 结合了低级语言的性能和控制能力,同时提供了高级语言的抽象和安全性。通过独特的所有权模型和内存管理机制,Rust 能有效避免空指针和数据竞争问题。本文将全面介绍 Rust 的语法、关键字和基础概念,并附有相关示例程序,帮助初学者快速入门。
目录
- Rust 简介
- 变量与绑定
- 解构
- 基本类型
- 复合类型
- 集合类型
- 流程控制
- 所有权与借用
- 模式匹配
- 方法与关联函数
- 泛型
- 特征
- 生命周期
- 错误处理
- 包与模块
- 打印与格式化输出
- 总结
1. Rust 简介
核心特点
- 内存安全:通过所有权模型管理内存,避免空指针、数据竞争等问题。
- 高性能:编译为机器码,无需垃圾回收器,性能媲美 C/C++。
- 并发性:编译时检测数据竞争,提供安全的并发编程支持。
- 多范式支持:支持函数式、面向对象和过程式编程。
Rust 由 Mozilla Research 于 2009 年开始开发,2010 年公开,并于 2015 年发布了第一个稳定版本(1.0)。Rust 社区和 Rust 团队共同维护该语言,每六周发布一个新版本,以持续改进语言特性和性能。
更多信息请参阅 Rust 官方网站。
2. 变量与绑定
在 Rust 中,变量默认是不可变的(immutable),这意味着一旦赋值后,变量的值不能被修改。如果需要可变变量,可以使用 mut 关键字。
示例代码
fn main() {
let x = 5; // 不可变变量
let mut y = 10; // 可变变量
y = 15; // 可以修改
println!("x = {}, y = {}", x, y);
}
此外,Rust 支持变量遮蔽(shadowing),允许使用相同的变量名重新绑定新的值。
变量遮蔽 (Shadowing)
fn main() {
let x = 5;
let x = x + 1; // 遮蔽之前的 x
println!("x = {}", x); // 输出 x = 6
}
3. 解构
Rust 支持解构赋值,可以用于元组、数组和结构体,从复杂数据结构中提取值。
示例代码
fn main() {
let (a, b, c) = (1, 2, 3); // 解构元组
println!("a = {}, b = {}, c = {}", a, b, c);
let [x, .., y] = [10, 20, 30, 40]; // 解构数组
println!("x = {}, y = {}", x, y);
}
4. 基本类型
Rust 提供多种基本类型,包括整数、浮点数、布尔值和字符。
数值类型
- 整数:
i8,i16,i32,i64,i128,u8,u16,u32,u64,u128,isize,usize - 浮点数:
f32,f64
fn main() {
// 整数
let int: i32 = 42;
let float: f64 = 3.14;
println!("int = {}, float = {}", int, float);
// 布尔类型
let is_active: bool = true;
println!("is_active = {}", is_active);
// 字符类型
let c: char = 'R';
println!("c = {}", c);
}
5. 复合类型
元组
元组是固定大小的有序集合,可以包含不同类型的元素。
fn main() {
let tup: (i32, f64, char) = (42, 3.14, 'R');
let (x, y, z) = tup;
println!("x = {}, y = {}, z = {}", x, y, z);
}
数组
数组是固定大小的序列,所有元素类型相同。
fn main() {
let arr: [i32; 3] = [1, 2, 3];
println!("arr[0] = {}", arr[0]);
}
6. 集合类型
动态数组 (Vector)
向量是动态大小的集合,允许在运行时增长或缩小。
fn main() {
let mut vec = vec![1, 2, 3];
vec.push(4);
println!("{:?}", vec); // 输出: [1, 2, 3, 4]
}
哈希表 (HashMap)
哈希映射(HashMap)用于存储键值对,提供快速的查找能力。
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert("key1", "value1");
println!("{:?}", map); // 输出: {"key1": "value1"}
}
7. 流程控制
条件语句
Rust 使用 if 和 else 来实现条件语句。
fn main() {
let number = 6;
if number % 2 == 0 {
println!("Even");
} else {
println!("Odd");
}
}
循环
Rust 提供了几种类型的循环,包括 loop、while 和 for。
fn main() {
// 无限循环
loop {
println!("loop");
break;
}
// while 循环
let mut x = 0;
while x < 5 {
println!("x: {}", x);
x += 1;
}
// for 循环
for i in 1..=5 {
println!("i = {}", i);
}
}
8. 所有权与借用
所有权
每个值都有一个所有者,这个所有者负责在值不再需要时释放它。Rust 的所有权规则确保了内存安全性。
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 的所有权转移到 s2
// println!("{}", s1); // 错误:s1 已失效
println!("{}", s2);
}
借用
借用允许你使用某个值而不需要获得其所有权。通过引用可以实现这一点。
fn main() {
let s = String::from("hello");
let len = calculate_length(&s); // 借用 s
println!("The length of '{}' is {}.", s, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
9. 模式匹配
模式匹配是 Rust 中一个强大的功能,允许你根据值的模式执行不同的代码块。主要通过 match 语句实现。
fn main() {
let number = 3;
match number {
1 => println!("One"),
2 => println!("Two"),
3 => println!("Three"),
_ => println!("Other"),
}
}
10. 方法与关联函数
方法
方法是与结构体或枚举相关联的函数,使用 impl 关键字定义。
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("The area of the rectangle is {} square pixels.", rect.area());
}
11. 泛型
泛型允许你编写可以适用于多种类型的代码,增加代码的复用性和灵活性。
fn largest(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
println!("The largest number is {}", largest(&number_list));
}
12. 特征
特征(trait)类似于其他语言中的接口或抽象类,它定义了一组方法,供实现该特征的类型使用。
trait Summary {
fn summarize(&self) -> String;
}
struct NewsArticle {
headline: String,
location: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{} ({})", self.headline, self.location)
}
}
fn main() {
let article = NewsArticle {
headline: String::from("Rust 入门教程"),
location: String::from("中国"),
};
println!("{}", article.summarize());
}
13. 生命周期
生命周期是 Rust 中用于管理引用有效性的一个概念,确保引用不会成为悬垂引用。
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() >= y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("最长的字符串是 {}", result);
}
14. 错误处理
Rust 提供了 Result 和 Option 类型来处理错误和可选值。Result 用于可恢复错误,而 panic! 用于不可恢复错误。
可恢复错误
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => {
panic!("Error opening file: {}", error);
},
};
}
不可恢复错误
fn main() {
panic!("Something went wrong!");
}
15. 包与模块
包 (Crate)
Rust 使用包(crate)和模块来组织代码。一个 Rust 包可以包含多个二进制目标和库目标。
// Cargo.toml
[package]
name = "my_package"
version = "0.1.0"
edition = "2021"
[dependencies]
模块
模块用于将代码分组和重用。
mod my_module {
pub fn my_function() {
println!("This is a function in the module.");
}
}
fn main() {
my_module::my_function();
}
16. 打印与格式化输出
Rust 提供了多种格式化输出的方式,如 println!、format! 等。
fn main() {
let name = "Alice";
let age = 30;
println!("My name is {} and I am {} years old.", name, age);
let formatted = format!("My name is {} and I am {} years old.", name, age);
println!("{}", formatted);
}
17. 总结
Rust 是一门功能强大且安全的语言,适合用于系统编程、高性能应用和并发场景。通过学习本文的基础知识,你可以快速上手 Rust 并编写高效、安全的程序。Rust 的学习曲线可能较陡,但掌握它后,你将能够利用其强大的特性编写可靠的软件。
Last updated January 4, 2025