title: "Rust 内存安全:所有权系统与零成本抽象"
date: "2026-07-10"
tags: ["Rust", "内存安全", "所有权", "系统编程"]
Rust 内存安全:所有权系统与零成本抽象
Rust 的所有权系统是其最核心的特性,它在编译时保证内存安全,无需垃圾回收。
所有权规则
RUST
fn main() {
// 规则 1: 每个值有且只有一个所有者
let s1 = String::from("hello");
// 规则 2: 同一时刻只能有一个所有者
let s2 = s1; // s1 的所有权移动到 s2
// println!("{}", s1); // 编译错误!s1 已无效
println!("{}", s2); // OK
}借用与引用
RUST
fn main() {
let s = String::from("hello");
// 不可变借用(可以有多个)
let r1 = &s;
let r2 = &s;
println!("{} and {}", r1, r2);
// 可变借用(同一时刻只能有一个)
let mut s = String::from("hello");
let r = &mut s;
r.push_str(", world");
println!("{}", r);
}生命周期
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("long string");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
println!("最长的字符串是 {}", result);
}
}智能指针
Box
RUST
// 堆上分配
fn main() {
let b = Box::new(5);
println!("b = {}", b);
}
// 递归类型
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
fn main() {
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}Rc 和 Arc
RUST
use std::rc::Rc;
use std::sync::Arc;
// 单线程引用计数
fn main() {
let a = Rc::new(String::from("hello"));
let b = Rc::clone(&a);
let c = Rc::clone(&a);
println!("引用计数: {}", Rc::strong_count(&a)); // 3
}
// 多线程引用计数
use std::thread;
fn main() {
let data = Arc::new(vec![1, 2, 3]);
let handles: Vec<_> = (0..3).map(|i| {
let data = Arc::clone(&data);
thread::spawn(move || {
println!("Thread {}: {:?}", i, data);
})
}).collect();
for handle in handles {
handle.join().unwrap();
}
}错误处理
RUST
use std::fs::File;
use std::io::{self, Read};
// Result 类型
fn read_file(path: &str) -> Result<String, io::Error> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
// Option 类型
fn find_user(id: u32) -> Option<String> {
if id == 1 {
Some(String::from("Alice"))
} else {
None
}
}
fn main() {
match read_file("hello.txt") {
Ok(contents) => println!("{}", contents),
Err(e) => eprintln!("错误: {}", e),
}
match find_user(1) {
Some(name) => println!("找到用户: {}", name),
None => println!("用户不存在"),
}
}零成本抽象
RUST
// 泛型在编译时单态化,无运行时开销
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
fn main() {
let sum_i32 = add(1, 2); // 编译为 i32 加法
let sum_f64 = add(1.0, 2.0); // 编译为 f64 加法
}
// trait 对象 vs 静态分发
trait Animal {
fn speak(&self);
}
struct Dog;
struct Cat;
impl Animal for Dog {
fn speak(&self) { println!("Woof!"); }
}
impl Animal for Cat {
fn speak(&self) { println!("Meow!"); }
}
// 静态分发(零成本)
fn make_speak_static<T: Animal>(animal: &T) {
animal.speak();
}
// 动态分发(有 vtable 开销)
fn make_speak_dynamic(animal: &dyn Animal) {
animal.speak();
}并发安全
RUST
use std::thread;
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
// val 已移动,无法再使用
});
let received = rx.recv().unwrap();
println!("收到: {}", received);
}
// 数据竞争在编译时被阻止
fn main() {
let mut data = vec![1, 2, 3];
// 编译错误!不能同时有可变和不可变引用
// let r = &data;
// data.push(4);
// println!("{}", r);
}Rust 的所有权系统让"如果它能编译,它就是安全的"成为现实。这种编译时保证消除了大量运行时错误,是系统编程的重大进步。
读者评论 2