作为一门兼具性能和安全性的系统编程语言,Rust在2026年已经成为许多开发者的首选。无论你是想要构建高性能的Web服务,还是开发系统级应用,Rust都能提供强大的支持。这篇文章将带你从零开始,系统性地学习Rust编程语言。

为什么选择Rust?

在开始学习之前,让我们先了解Rust的核心优势:

内存安全

Rust通过所有权系统在编译时防止内存泄漏、空指针解引用等常见错误,无需垃圾回收器就能保证内存安全。

零成本抽象

Rust的抽象不会带来运行时开销,你可以编写高级代码而不牺牲性能。

并发安全

Rust的类型系统能在编译时防止数据竞争,让并发编程变得更加安全。

跨平台支持

一次编写,到处编译,支持从嵌入式设备到服务器的各种平台。

环境搭建

安装Rust

最简单的方式是使用rustup:

1
2
3
4
# Windows
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 或者访问 https://rustup.rs/ 下载安装程序

安装完成后,验证安装:

1
2
rustc --version
cargo --version

第一个Rust程序

创建一个新项目:

1
2
cargo new hello_rust
cd hello_rust

查看生成的src/main.rs:

1
2
3
fn main() {
println!("Hello, world!");
}

运行程序:

1
cargo run

Rust基础概念

变量和可变性

Rust中的变量默认是不可变的:

1
2
3
4
5
6
7
8
9
10
11
12
fn main() {
let x = 5;
// x = 6; // 这会报错!

let mut y = 5;
y = 6; // 这是可以的

// 变量遮蔽
let x = x + 1;
let x = x * 2;
println!("x的值是: {}", x); // 输出: 12
}

数据类型

Rust是静态类型语言,编译时必须知道所有变量的类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn main() {
// 整数类型
let a: i32 = 42;
let b = 42u64; // 类型后缀

// 浮点类型
let c = 3.14; // f64
let d: f32 = 3.14;

// 布尔类型
let is_true = true;

// 字符类型
let heart = '💖';

// 字符串
let hello = "Hello, Rust!";
let mut owned_string = String::from("Hello");
owned_string.push_str(", Rust!");
}

函数

Rust中的函数定义使用fn关键字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main() {
let result = add(5, 3);
println!("5 + 3 = {}", result);

let (sum, product) = calculate(4, 6);
println!("和: {}, 积: {}", sum, product);
}

fn add(a: i32, b: i32) -> i32 {
a + b // 注意:没有分号,这是表达式
}

// 返回多个值
fn calculate(a: i32, b: i32) -> (i32, i32) {
(a + b, a * b)
}

所有权系统:Rust的核心

所有权是Rust最独特也是最重要的特性:

所有权规则

  1. Rust中的每个值都有一个所有者
  2. 值在任意时刻只能有一个所有者
  3. 当所有者离开作用域,这个值将被丢弃
1
2
3
4
5
6
7
8
9
10
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1的所有权移动到s2

// println!("{}", s1); // 错误!s1不再有效
println!("{}", s2); // 正确

let s3 = s2.clone(); // 深拷贝
println!("s2: {}, s3: {}", s2, s3); // 都有效
}

借用和引用

借用允许你使用值而不获取其所有权:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn main() {
let s1 = String::from("hello");

let len = calculate_length(&s1); // 借用
println!("'{}'的长度是 {}", s1, len); // s1仍然有效

let mut s2 = String::from("hello");
change(&mut s2); // 可变借用
println!("{}", s2);
}

fn calculate_length(s: &String) -> usize {
s.len()
} // s离开作用域,但因为它不拥有引用的数据,所以什么也不会发生

fn change(s: &mut String) {
s.push_str(", world");
}

切片

切片让你引用集合中一段连续的元素序列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main() {
let s = String::from("hello world");

let hello = &s[0..5]; // 或 &s[..5]
let world = &s[6..11]; // 或 &s[6..]
let whole = &s[..]; // 整个字符串

let first_word = first_word(&s);
println!("第一个单词: {}", first_word);
}

fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();

for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}

&s[..]
}

结构体和枚举

结构体

结构体让你创建自定义数据类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#[derive(Debug)]
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}

impl User {
// 关联函数(类似静态方法)
fn new(username: String, email: String) -> User {
User {
username,
email,
active: true,
sign_in_count: 1,
}
}

// 方法
fn is_active(&self) -> bool {
self.active
}

fn deactivate(&mut self) {
self.active = false;
}
}

fn main() {
let mut user = User::new(
String::from("张三"),
String::from("zhangsan@example.com"),
);

println!("用户信息: {:?}", user);
println!("用户是否活跃: {}", user.is_active());

user.deactivate();
println!("停用后: {}", user.is_active());
}

枚举

枚举让你定义一个类型,它可以是几个可能的变体之一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#[derive(Debug)]
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}

impl Message {
fn process(&self) {
match self {
Message::Quit => println!("退出消息"),
Message::Move { x, y } => println!("移动到 ({}, {})", x, y),
Message::Write(text) => println!("写入文本: {}", text),
Message::ChangeColor(r, g, b) => {
println!("改变颜色为 RGB({}, {}, {})", r, g, b)
}
}
}
}

fn main() {
let messages = vec![
Message::Write(String::from("Hello")),
Message::Move { x: 10, y: 20 },
Message::ChangeColor(255, 0, 0),
Message::Quit,
];

for message in messages {
message.process();
}
}

错误处理

Rust使用Result<T, E>类型来处理可能失败的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
use std::fs::File;
use std::io::ErrorKind;

fn main() {
// 使用match处理Result
let file_result = File::open("hello.txt");
let _file = match file_result {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => {
println!("文件不存在,创建新文件");
File::create("hello.txt").unwrap_or_else(|error| {
panic!("创建文件失败: {:?}", error);
})
}
other_error => panic!("打开文件出错: {:?}", other_error),
},
};

// 使用?操作符简化错误处理
let content = read_file_content("hello.txt");
match content {
Ok(text) => println!("文件内容: {}", text),
Err(e) => println!("读取失败: {}", e),
}
}

fn read_file_content(filename: &str) -> Result<String, std::io::Error> {
use std::fs;
fs::read_to_string(filename) // ?操作符会自动传播错误
}

集合类型

Vector

动态数组,可以存储多个相同类型的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() {
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);

let v2 = vec![1, 2, 3, 4, 5];

// 访问元素
let third = &v2[2];
println!("第三个元素是 {}", third);

match v2.get(2) {
Some(third) => println!("第三个元素是 {}", third),
None => println!("没有第三个元素"),
}

// 遍历
for i in &v2 {
println!("{}", i);
}

// 可变遍历
for i in &mut v {
*i += 50;
}
}

HashMap

键值对集合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
use std::collections::HashMap;

fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("蓝队"), 10);
scores.insert(String::from("红队"), 50);

// 从向量创建
let teams = vec![String::from("蓝队"), String::from("红队")];
let initial_scores = vec![10, 50];
let scores2: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();

// 访问值
let team_name = String::from("蓝队");
let score = scores.get(&team_name);

// 遍历
for (key, value) in &scores {
println!("{}: {}", key, value);
}

// 只在键没有对应值时插入
scores.entry(String::from("黄队")).or_insert(0);

// 根据旧值更新
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}", map);
}

实战项目:猜数字游戏

让我们通过一个完整的项目来巩固所学知识:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("猜数字游戏!");

let secret_number = rand::thread_rng().gen_range(1..101);

loop {
println!("请输入你的猜测:");

let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("读取输入失败");

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("请输入一个有效的数字!");
continue;
}
};

println!("你猜测的数字是: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less => println!("太小了!"),
Ordering::Greater => println!("太大了!"),
Ordering::Equal => {
println!("你赢了!");
break;
}
}
}
}

记得在Cargo.toml中添加依赖:

1
2
[dependencies]
rand = "0.8"

学习建议和下一步

循序渐进的学习路径

  1. 掌握基础语法:变量、函数、控制流
  2. 理解所有权系统:这是Rust的核心,需要多练习
  3. 学习结构体和枚举:构建复杂数据类型
  4. 掌握错误处理:Result和Option的使用
  5. 熟悉集合类型:Vec、HashMap等常用集合
  6. 学习模块系统:组织大型项目的代码
  7. 并发编程:利用Rust的并发安全特性

实践项目建议

  • CLI工具:文件处理、文本分析工具
  • Web服务:使用Axum或Actix-web构建API
  • 系统工具:文件监控、日志分析工具
  • 游戏开发:简单的2D游戏或文字游戏

学习资源

  • 官方文档:The Rust Book
  • 练习平台:Rustlings、Exercism
  • 社区:Rust用户论坛、Discord社区
  • 实战项目:GitHub上的开源Rust项目

结语

Rust是一门值得投资时间学习的语言。虽然初期的学习曲线可能比较陡峭,但一旦掌握了所有权系统等核心概念,你会发现Rust能让你编写出既安全又高效的代码。

在2026年,Rust已经在系统编程、Web开发、区块链、游戏开发等多个领域证明了自己的价值。对于想要构建高性能、可靠软件的开发者来说,Rust是一个绝佳的选择。

记住,学习编程语言最好的方式就是实践。从小项目开始,逐步挑战更复杂的任务,你会在这个过程中真正掌握Rust的精髓。


这篇导学基于Rust官方教程,结合2026年的实际应用场景。希望能帮助你开启Rust编程之旅!