阶段二:基础(Rust 核心概念)

72 阅读2分钟

目标

理解 Rust 独特的所有权、借用与生命周期机制,能写稍复杂程序。


1. 所有权系统(Ownership)

Rust 的核心理念是内存安全:每个值在任意时刻只能有一个所有者,所有者离开作用域时,值会被释放。

fn main() {
    let s1 = String::from("hello"); // s1 拥有这个字符串
    let s2 = s1; // 移动(Move),s1 不再有效
    // println!("{}", s1); // 错误!s1 已被移动
    println!("{}", s2);
}

克隆(Clone)

let s1 = String::from("hello");
let s2 = s1.clone(); // 显式克隆,s1 仍然可用
println!("s1 = {}, s2 = {}", s1, s2);

可变性

let mut x = 5;
x += 1;
println!("{}", x);

2. 借用与引用

Rust 允许临时借用值,而不转移所有权。

不可变引用

fn main() {
    let s = String::from("hello");
    let len = calculate_length(&s); // 借用 s
    println!("长度: {}", len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

可变引用

fn main() {
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);
}

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

借用检查器规则

  • 在同一时间,只能有一个可变引用,或多个不可变引用
  • 防止数据竞争

3. 生命周期(Lifetimes)

生命周期确保引用在有效范围内使用。

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let s1 = String::from("hello");
    let s2 = String::from("world");
    let result = longest(&s1, &s2);
    println!("最长的是 {}", result);
}
  • 'a 表示引用的生命周期
  • 生命周期也可以用于结构体:
struct Book<'a> {
    title: &'a str,
}

4. 结构体与枚举

结构体

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!("面积: {}", rect.area());
}

枚举

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

Option 与 Result

let some_number: Option<i32> = Some(5);
let no_number: Option<i32> = None;

let result: Result<i32, &str> = Ok(10);
let error: Result<i32, &str> = Err("出错了");

5. 集合与迭代器

Vec

let mut v = vec![1, 2, 3];
v.push(4);
for i in &v {
    println!("{}", i);
}

HashMap

use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("Alice", 10);
scores.insert("Bob", 20);

迭代器和高阶函数

let v = vec![1, 2, 3, 4];
let v2: Vec<_> = v.iter().map(|x| x * 2).collect();
println!("{:?}", v2); // [2,4,6,8]

6. 错误处理

panic! 宏

panic!("程序出错!");

Result<T, E>

use std::fs::File;

fn main() -> std::io::Result<()> {
    let f = File::open("hello.txt")?;
    Ok(())
}

unwrap / expect / ?

let f = File::open("hello.txt").expect("无法打开文件");

练习建议

  1. 命令行记账程序
  • 输入金额和备注,保存到 Vec 或文件中
  • 统计总金额
  • 保存/读取文件
  1. 文件读取与写入
use std::fs;

fn main() {
    let contents = fs::read_to_string("data.txt").expect("读取失败");
    println!("文件内容:\n{}", contents);
}