Rust 所有权与借用机制:彻底理解生命周期

Choyeon· 2026年9月7日· 2 分钟阅读· 254 阅读· 594 字· 1,599 字符· 更新于 2026年10月1日
Rust 所有权与借用机制:彻底理解生命周期

Rust 不用 GC 却能保证内存安全,核心武器是所有权系统和借用检查器。编译期检查内存访问合法性,运行时零开销,但理解门槛是主流语言中最高的。

三大所有权铁律

1)每个值有且仅有一个所有者;2)所有者离开作用域,值立即被 drop;3)同一值最多只能有一个可变引用,可变和不可变引用不能同时存在。几乎所有初学生命周期错误都是违背第3条。

use std::collections::HashMap;

#[derive(Debug, Clone)]
struct User { id: u32, username: String, profile: Option<Box<User>> }

struct UserCache<'a> {
    users: HashMap<u32, User>,
    last_accessed: Option<&'a User>,
}

impl<'a> UserCache<'a> {
    fn new() -> Self { Self { users: HashMap::new(), last_accessed: None } }
    fn insert(&mut self, user: User) { self.users.insert(user.id, user); }
    fn get(&'a mut self, id: u32) -> Option<&'a User> {
        if let Some(u) = self.users.get(&id) {
            self.last_accessed = Some(u);
            self.last_accessed
        } else { None }
    }
}

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

struct Parser<'s, 'b> where 's: 'b { source: &'s str, buffer: &'b mut [u8] }

impl<'s, 'b> Parser<'s, 'b> where 's: 'b {
    fn new(source: &'s str, buffer: &'b mut [u8]) -> Self { Self { source, buffer } }
}

fn main() {
    let s1 = String::from("hello");
    let s2 = s1.clone();
    println!("s1={s1}, s2={s2}");
    let a = String::from("short"); let b = String::from("longest string wins");
    println!("longest: {}", longest_str(&a, &b));
    let mut cache = UserCache::new();
    cache.insert(User { id: 1, username: "rosetta".into(), profile: None });
    let u = cache.get(1);
    println!("Got user: {:?}", u.map(|x| &x.username));
    let mut buf = vec![0u8; 1024];
    let p = Parser::new("input", buf.as_mut_slice());
    println!("Parser source len: {}", p.source.len());
}

生命周期标注与约束

当函数/结构体中出现引用时,Rust 需要显式生命周期标注('a、'b)告知编译器引用有效期关系。's: 'b 表示 's 存活时间不短于 'b,常见于结构体自引用场景。

常见错误 本质 修复模式
use of moved value 所有权被转移 .clone()/用&borrow
cannot borrow X mutable+immutable 违反借用规则 缩小作用域/分块
missing lifetime specifier 编译器推不出 加'a关联输入输出
lifetime may not live long enough 引用先被释放 延长作用域/改用拥有所有权类型

最佳实践

写代码初期全用拥有所有权类型(String/Vec/Box),编译通过后再按需改为引用。不要过早纠结生命周期标注,让编译器给你驱动式修改建议。

本文作者

评论 (0)

暂无评论,来抢沙发吧。