共享引用

引用提供了一种可以访问另一个值但无需对该值负责的方式,也被称为 “借用”。共享引用处于只读状态,且引用的数据无法更改。

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.count_ones()). 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)。