第9章 - 引用与借用
嗨,朋友!我是长安。
上一章我们学习了所有权,发现每次传递值都会转移所有权,很不方便。这一章我们学习引用(Reference)和借用(Borrowing),让你可以使用值而不获取所有权。
🔗 什么是引用?
引用就像是值的"临时通行证",你可以使用值,但不拥有它。
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1); // 传递引用,不转移所有权
println!("字符串 '{}' 的长度是 {}", s1, len); // s1 依然有效!
}
fn calculate_length(s: &String) -> usize {
s.len()
} // s 离开作用域,但因为它不拥有数据,所以什么都不会发生
使用 & 创建引用,这个过程叫做借用(borrowing)。
长安说
引用就像借书:你可以读书(使用值),但书的所有权还是属于图书馆(原变量)。读完了要还回去!
🔒 不可变引用
默认情况下,引用是不可变的:
fn main() {
let s = String::from("hello");
change(&s); // ❌ 编译错误
}
fn change(some_string: &String) {
some_string.push_str(", world"); // 不能修改借用的值
}
🔓 可变引用
如果需要修改借用的值,使用可变引用 &mut:
fn main() {
let mut s = String::from("hello");
change(&mut s);
println!("{}", s); // 输出:hello, world
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
⚠️ 借用规则
Rust 有严格的借用规则:
在同一时间,你只能拥有以下之一:
- 一个可变引用
- 任意数量的不可变引用
引用必须总是有效的
fn main() {
let mut s = String::from("hello");
let r1 = &s; // ✅ 不可变引用
let r2 = &s; // ✅ 再来一个不可变引用
println!("{} and {}", r1, r2);
let r3 = &mut s; // ✅ 可变引用(r1 和 r2 已经不再使用)
println!("{}", r3);
}
但这样不行:
fn main() {
let mut s = String::from("hello");
let r1 = &s; // 不可变引用
let r2 = &mut s; // ❌ 错误!不能在有不可变引用时创建可变引用
println!("{}, {}", r1, r2);
}
长安说
为什么有这个规则?
想象你在读一本书(不可变引用),突然有人修改了这本书的内容(可变引用),你读到的信息就不一致了!Rust 通过借用规则防止这种情况。
💡 小结
- 使用
&创建引用(借用) - 引用让你使用值而不获取所有权
- 默认引用是不可变的
- 使用
&mut创建可变引用 - 同一时间只能有一个可变引用,或多个不可变引用
