Rust引用和借用
提示
- 引用与借用概念:Rust中的引用允许指向值而不拥有它,这称为借用。当函数需要值但不改变所有权时,引用非常有用。
- 引用的使用和修改:默认情况下,引用是不可变的,但可以通过
&mut
关键字创建可变引用。这允许函数修改借用的值。 - Rust引用规则:在任何时候,你可以拥有一个可变引用或多个不可变引用,但不能同时拥有两者。引用必须始终有效,以避免悬垂引用。
引用 在 Rust 中允许我们指向一个资源(值)而不拥有 它。这意味着资源的原始所有者保持不变。
当传递值给一个我们不想改变所有权的函数时,引用非常有用。创建引用被称为 Rust 中的借用。
理解 Rust 中的引用
让我们看一个例子来了解 Rust 中的引用。
fn main() {
let str = String::from("Hello, World!");
// 使用引用 String 值调用函数
let len = calculate_length(&str);
println!("'{}' 的长度是 {}。", str, len);
}
// 计算字符串长度的函数
// 它接受一个 String 的引用作为参数
fn calculate_length(s: &String) -> usize {
s.len()
}
输出
'Hello, World!' 的长度是 13。
在上述示例中,我们定义了一个名为 calculate_length()
的函数,它接受一个 &String
类型作为参数。
重要的部分是 s
是一个指向 String
的引用,并且它没有拥有 String
的实际值。
fn calculate_length(s: &String) -> usize { // s 是一个指向 String 的引用
s.len()
}
当 s
在函数结束时离开作用域,它不会被丢弃,因为它没有拥有它所引用的内容的所有权。
函数调用看起来像这样:
let str = String::from("Hello, World!");
let len = calculate_length(&str);
在调用函数时使用 &str
语法,让我们创建了一个引用,它指向 str
的值,但并不拥有它。
创建引用的行为被称为 借用。借用是当我们借用某物时,使用完后,我们会归还它。这并不使我们成为数据的所有者。
注意: 和号 (&) 代表引用,它们允许我们引用某个值,而不拥有它。
在 Rust 中修改引用
默认情况下,引用始终是不可变的。然而,我们可以使用 &mut
关键字使引用可变。
例如,
fn main() {
let mut str = String::from("Hello");
// 修改字符串前
println!("Before: str = {}", str);
// 调用函数时传递一个可变字符串
change(&mut str);
// 修改字符串后
println!("After: str = {}", str);
}
fn change(s: &mut String) {
// 向可变引用变量推送字符串
s.push_str(", World!");
}
输出
Before: str = Hello
After: str = Hello, World!
这里,我们将变量 str
设置为可变的。然后我们使用 &mut str
创建一个可变引用,并用可变引用 s: &mut String
调用 change()
函数。
这允许 change()
函数修改它借用的值。在 change()
函数中,我们用 s.push_str(", World!")
向引用字符串推送字符串。
注意: 如果你有一个值的可变引用,你不能有该值的其他任何引用。
fn main() {
let mut str = String::from("hello");
// 可变引用 1
let ref1 = &mut str;
// 可变引用 2
let ref2 = &mut str;
println!("{}, {}", ref1, ref2);
}
输出
error[E0499]: 不能同时多次借用 `str` 为可变
--> src/main.rs:8:16
|
5 | let ref1 = &mut str;
| -------- 第一次可变借用发生在这里
...
8 | let ref2 = &mut str;
|
^^^^^^^^ 第二次可变借用发生在这里
9 |
10 | println!("{}, {}", ref1, ref2);
| ---- 第一次借用后续在这里使用
引用规则
Rust 主要遵循以下引用规则:
- 在任何给定时间,你可以拥有一个可变引用 或任意数量的不可变引用。
- 引用必须始终有效。