# Rust 入门教程
Rust 入门教程
目录
1. 安装与环境配置
# 安装 Rust(使用 rustup)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 验证安装
rustc --version
cargo --version
# 更新 Rust
rustup updateIDE 推荐
- VS Code +
rust-analyzer插件 - RustRover(JetBrains)
- vim/neovim + rust-analyzer LSP
2. Hello World
# 创建项目
cargo new hello_rust
cd hello_rust// src/main.rs
fn main() {
println!("Hello, Rust!");
}# 编译并运行
cargo run
# 只编译(不运行)
cargo build # debug 模式
cargo build --release # release 模式(优化)Cargo 常用命令
| 命令 | 作用 |
|---|---|
cargo new | 创建新项目 |
cargo run | 编译+运行 |
cargo build | 编译 |
cargo check | 检查语法(不编译,快) |
cargo test | 运行测试 |
cargo fmt | 格式化代码 |
cargo clippy | 代码规范检查 |
3. 变量与基本类型
变量默认不可变
fn main() {
// 不可变变量(默认)
let x = 5;
// x = 6; // ❌ 编译错误!
// 可变变量
let mut y = 5;
y = 6; // ✅
// 常量(全大写,必须标注类型)
const MAX_POINTS: u32 = 100_000;
}基础类型
fn main() {
// --- 整数 ---
let a: i32 = 42; // 有符号 32 位(默认)
let b: u64 = 100; // 无符号 64 位
let c: usize = 10; // 指针大小(数组索引用)
// --- 浮点数 ---
let pi: f64 = 3.14159; // 双精度(默认)
let e: f32 = 2.71828; // 单精度
// --- 布尔 ---
let is_rust_fun: bool = true;
// --- 字符(4 字节,支持 Unicode)---
let heart_emoji = '❤';
let chinese = '中';
// --- 元组 ---
let tup: (i32, f64, char) = (500, 6.4, 'A');
let (x, y, z) = tup; // 解构
println!("{}", tup.0); // 索引访问
// --- 数组(固定长度,栈上分配)---
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let zeros = [0; 100]; // 100 个 0
println!("{}", arr[0]); // 索引访问
}字符串
fn main() {
// &str:字符串切片(不可变,借用)
let s1: &str = "hello";
// String:堆上分配,可增长
let mut s2 = String::from("hello");
s2.push_str(", world!");
s2.push('!');
// 拼接
let s3 = format!("{s1}, {s2}");
// 遍历
for c in "नमस्ते".chars() {
println!("{c}");
}
}4. 所有权(核心概念)
Rust 没有 GC,不需要手动 free,全靠所有权系统。
三大规则
fn main() {
// 规则 1:每个值有且只有一个所有者
let s1 = String::from("hello");
let s2 = s1; // s1 所有权转移给 s2
// println!("{s1}"); // ❌ s1 已失效!
// 规则 2:离开作用域自动释放
{
let s3 = String::from("world");
} // s3 在这里自动释放
// 规则 3:同一时刻,要么一个可变引用,要么多个不可变引用
let mut s = String::from("hello");
let r1 = &s; // 不可变借用
let r2 = &s; // 可以有多个不可变借用
// let r3 = &mut s; // ❌ 不能同时有可变和不可变借用
println!("{r1} {r2}"); // r1, r2 最后使用
let r3 = &mut s; // ✅ r1, r2 已经不用了
r3.push_str(" world");
}借用可视化
所有者: s ──→ String "hello"
│
不可变借用: r1 ──┤ (同时可以有很多个)
r2 ──┘
│
可变借用: r3 ────→ (只能有一个,且不能与不可变借用共存)5. 函数与控制流
fn main() {
// 调用函数
let result = add(3, 5);
println!("3 + 5 = {result}");
// --- if 是表达式 ---
let number = 42;
let description = if number > 50 {
"big"
} else if number > 0 {
"positive"
} else {
"zero or negative"
};
println!("{number} is {description}");
// --- loop ---
let mut count = 0;
let result = loop {
count += 1;
if count == 10 {
break count * 2; // break 可以返回值
}
};
println!("loop result: {result}");
// --- while ---
let mut n = 3;
while n > 0 {
println!("{n}!");
n -= 1;
}
println!("LIFTOFF!");
// --- for(最常用)---
let arr = [10, 20, 30, 40, 50];
for element in arr {
println!("the value is: {element}");
}
// 范围
for i in (1..4).rev() { // 3, 2, 1
println!("{i}");
}
}
// 函数定义
fn add(x: i32, y: i32) -> i32 {
x + y // 最后一行是返回值(不加分号)
// 等价于 return x + y;
}6. 结构体与枚举
结构体
// 普通结构体
struct User {
username: String,
email: String,
active: bool,
}
// 元组结构体
struct Color(u8, u8, u8);
struct Point(i32, i32);
// 单元结构体(标记类型)
struct AlwaysEqual;
impl User {
// 关联函数(构造函数)
fn new(username: String, email: String) -> Self {
Self {
username,
email,
active: true,
}
}
// 方法
fn deactivate(&mut self) {
self.active = false;
}
fn is_active(&self) -> bool {
self.active
}
}
fn main() {
// 创建实例
let mut user = User::new(
String::from("alice"),
String::from("alice@example.com"),
);
user.deactivate();
println!("active: {}", user.is_active());
let black = Color(0, 0, 0);
println!("red: {}", black.0);
}枚举与模式匹配
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(u8, u8, u8),
}
impl Message {
fn call(&self) {
match self {
Message::Quit => println!("Quit!"),
Message::Move { x, y } => println!("Move to ({x}, {y})"),
Message::Write(text) => println!("Write: {text}"),
Message::ChangeColor(r, g, b) => println!("Color: ({r}, {g}, {b})"),
}
}
}
// Option<T>:标准库中最常用的枚举
fn divide(a: f64, b: f64) -> Option<f64> {
if b == 0.0 {
None
} else {
Some(a / b)
}
}
fn main() {
let msg = Message::Write(String::from("hello"));
msg.call();
// 处理 Option
match divide(10.0, 2.0) {
Some(result) => println!("Result: {result}"),
None => println!("Cannot divide by zero"),
}
// if let 简化
let config_max = Some(3u8);
if let Some(max) = config_max {
println!("Max configured: {max}");
}
}7. 错误处理
可恢复错误:Result<T, E>
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
// 方式 1:match
let mut file = match File::open("username.txt") {
Ok(f) => f,
Err(e) => return Err(e),
};
let mut username = String::new();
match file.read_to_string(&mut username) {
Ok(_) => Ok(username),
Err(e) => Err(e),
}
}
// 方式 2:? 运算符(简洁版)
fn read_username_short() -> Result<String, io::Error> {
let mut username = String::new();
File::open("username.txt")?.read_to_string(&mut username)?;
Ok(username)
}
// 方式 3:标准库一行版
fn read_username_oneliner() -> Result<String, io::Error> {
std::fs::read_to_string("username.txt")
}
fn main() {
match read_username_short() {
Ok(name) => println!("Username: {name}"),
Err(e) => eprintln!("Error: {e}"),
}
}不可恢复错误:panic!
fn main() {
// 开发时使用
let v = vec![1, 2, 3];
// v[99]; // panic! 索引越界
// 手动触发
panic!("Something went horribly wrong!");
}8. 泛型与 Trait
// 泛型函数
fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
// Trait 定义
trait Summary {
fn summarize(&self) -> String;
// 默认实现
fn summarize_default(&self) -> String {
String::from("(Read more...)")
}
}
struct Article {
title: String,
content: String,
}
impl Summary for Article {
fn summarize(&self) -> String {
format!("{} - {}", self.title, &self.content[..50.min(self.content.len())])
}
}
// Trait 作为参数
fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
// 等价写法(trait bound)
fn notify2<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
fn main() {
let numbers = vec![3, 7, 2, 9, 1];
println!("Largest: {}", largest(&numbers));
let article = Article {
title: String::from("Rust is awesome!"),
content: String::from("Learn Rust today. It will change your life."),
};
notify(&article);
}
评论已关闭