Appearance
Rust 所有权
所有权是 Rust 最独特的特性之一,它让 Rust 在不需要垃圾回收的情况下保证内存安全。本章节将介绍 Rust 的所有权系统。
所有权规则
Rust 的所有权系统有以下三条规则:
- 每个值都有一个所有者:每个值在 Rust 中都有且只有一个所有者变量。
- 所有者离开作用域时,值会被丢弃:当所有者变量离开作用域时,它所拥有的值会被自动释放。
- 一个值只能有一个所有者:当值被赋给另一个变量时,所有权会转移。
所有权转移
基本类型的所有权
对于基本类型(如整数、布尔值等),赋值时会进行复制,而不是所有权转移:
rust
fn main() {
let x = 5;
let y = x; // 复制 x 的值
println!("x = {}, y = {}", x, y); // 可以同时使用 x 和 y
}复杂类型的所有权
对于复杂类型(如字符串、向量等),赋值时会发生所有权转移:
rust
fn main() {
let s1 = String::from("hello");
let s2 = s1; // 所有权从 s1 转移到 s2
// println!("s1 = {}", s1); // 错误:s1 不再拥有值
println!("s2 = {}", s2); // 正确:s2 现在拥有值
}函数调用时的所有权
当函数接收参数时,所有权会转移:
rust
fn take_ownership(s: String) {
println!("Got string: {}", s);
// s 离开作用域,值被释放
}
fn main() {
let s = String::from("hello");
take_ownership(s);
// println!("s = {}", s); // 错误:s 不再拥有值
}返回值的所有权
函数可以通过返回值转移所有权:
rust
fn give_ownership() -> String {
let s = String::from("hello");
s // 返回 s,所有权转移给调用者
}
fn main() {
let s = give_ownership();
println!("Got string: {}", s);
}借用
为了避免所有权转移带来的不便,Rust 提供了借用机制:
不可变借用
rust
fn print_string(s: &String) {
println!("String: {}", s);
// s 是借用的,不会获取所有权
}
fn main() {
let s = String::from("hello");
print_string(&s); // 传递引用
println!("s = {}", s); // 仍然可以使用 s
}可变借用
rust
fn modify_string(s: &mut String) {
s.push_str(", world");
}
fn main() {
let mut s = String::from("hello");
modify_string(&mut s); // 传递可变引用
println!("s = {}", s); // s 被修改了
}借用规则
- 同一时间只能有一个可变借用或多个不可变借用:不能同时有可变借用和不可变借用。
- 借用必须在所有者的作用域内:借用的生命周期不能超过所有者的生命周期。
rust
fn main() {
let mut s = String::from("hello");
let r1 = &s; // 不可变借用
let r2 = &s; // 另一个不可变借用,允许
// let r3 = &mut s; // 错误:不能同时有不可变借用和可变借用
println!("r1 = {}, r2 = {}", r1, r2);
// r1 和 r2 离开作用域
let r3 = &mut s; // 现在可以可变借用
println!("r3 = {}", r3);
}生命周期
生命周期是 Rust 中用于确保引用有效性的机制。生命周期注解使用撇号 ' 表示:
rust
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 = "world";
let result = longest(&s1, s2);
println!("Longest: {}", result);
}总结
- 所有权规则:每个值有一个所有者,所有者离开作用域时值被丢弃,一个值只能有一个所有者
- 所有权转移:复杂类型赋值时会发生所有权转移
- 借用:通过引用借用值,避免所有权转移
- 借用规则:同一时间只能有一个可变借用或多个不可变借用
- 生命周期:确保引用的有效性
所有权系统是 Rust 内存安全的核心,它让 Rust 在不需要垃圾回收的情况下保证内存安全。通过本章节的学习,你应该已经理解了 Rust 的所有权系统的基本概念和使用方法。