共享引用
引用提供了一种可以访问另一个值但无需对该值负责的方式,也被称为 “借用”。共享引用处于只读状态,且引用的数据无法更改。
fn main() {
let a = 'A';
let b = 'B';
let mut r: &char = &a;
println!("r: {}", *r);
r = &b;
println!("r: {}", *r);
}
对类型 T
的共享引用表示为 &T
。可以使用 &
运算符创建引用值。*
运算符会 “解引用”某个引用,并得到该引用值。
Rust 会静态禁止悬垂引用:
fn x_axis(x: i32) -> &(i32, i32) {
let point = (x, 0);
return &point;
}
This slide should take about 10 minutes.
引用被称为 “借用”了其所引用的值,这对于不熟悉指针的学生来说是一个很好的模型:代码可以通过引用来访问值,但原始变量仍然保有对该值的 “所有权”。本课程会在第 3 天详细介绍所有权。
引用是以指针的形式实现的,其关键优势在于它们可以比其所指的内容小得多。熟悉 C 或 C++ 的学生会将引用视为指针。本课程的后续部分将介绍 Rust 如何防止因使用原始指针而导致的内存安全 bug。
Rust 不会自动为您创建引用,必须始终使用
&
符号。Rust will auto-dereference in some cases, in particular when invoking methods (try
r.is_ascii()
). There is no need for an->
operator like in C++.在本例中,
r
是可变的,因此可以为其重新赋值 (r = &b
)。请注意,这会重新绑定r
,使其引用其他内容。这与 C++ 不同,在 C++ 中为引用赋值会更改引用的值。共享引用不允许修改其所引用的值,即使该值是可变的。请尝试
*r = 'X'
。Rust 会跟踪所有引用的生命周期,以确保它们存在足够长的时间。在安全的 Rust 中不会出现悬空引用。
x_axis
会返回对point
的引用,但point
会在该函数返回时取消分配,因此不会进行编译。我们会在讲到所有权(ownership)时详细讨论借用(borrow)。