跟着谷歌安卓团队学习Rust-引用与借用

153 阅读4分钟

大家好,我是梦兽编程。欢迎回来与梦兽编程一起刷Rust的系列。

这是由 Google 的 Android 团队开发的免费 Rust 课程。本课程涵盖了 Rust 的方方面面,从基本语法到泛型和错误处理等高级主题。

该课程的最新版本可以在 google.github.io/comprehensi…

如果你喜欢看梦兽编程的版本可以定义跟着谷歌安卓团队学Rust定于最新内容,梦兽编程也期待大家关注我的个人网站。

引用

与C++一样,Rust一样提供了引用的概念在Rust中。

引用是一种指向另一个值的变量。引用可以是可变的(mutable)或不可变的(immutable)。

Rust的引用非常简单

引用的语法很简单,就是在变量名之前加上一个&符号。例如,以下代码定义了一个可变引用:

fn main() {
    let mut x: i32 = 10;
    let ref_x: &mut i32 = &mut x;
    *ref_x = 20;
    println!("x: {x}");
}

以上代码,如果我们修改了ref_x的值,我们x值也会同时被改变,这就是引用的作用。

在内存中其实是指向了同一块内存地址。我们可以使用type_of方法进行对比,可以发现基础类型的地址是指向同一块。

assert_eq!(type_of!(ref_x), type_of!(x));
// output
// ture

注意悬垂引用

Rust 其实是一个半自动的内存机制,也就是在代码块执行后Rust会尝试给我们释放资源比如以下代码:

fn main() {
    let ref_x: &i32;
    {
        let x: i32 = 10;
        ref_x = &x;
    }
    println!("ref_x: {ref_x}");
}

在这种请求下,在别的生命周期中进行了一次引用我们又把这种引用叫做借用。在这种情况下我们需要保证我们的我们引用的变量活的比较久。

这是因为 ref_x 在 { } 块内被初始化为 &x,但 x 在 { } 块结束时被销毁。因此,ref_x 在 { } 块结束时仍然引用一个已经被销毁的值,这会导致悬垂引用。

什么是借用?

Rust 的借用机制是 Rust 语言中的一个重要概念。借用机制可以帮助 Rust 编译器确保引用的安全性,避免悬垂引用。

在 Rust 中,借用是指引用一个值的权利。引用可以是不可变的(immutable)或可变的(mutable)。 不可变引用只能读取引用的值,不能修改引用的值。可变引用可以读取和修改引用的值。

借用没有和网上过多的复杂概念,它只不过是你对引用值的使用权限是否有写的操作。

借用的规则

在 Rust 中,借用遵循以下规则:

  • 同一个作用域内,引用必须是有效的。最经典的反面例子就是返回局部变量的引用:
fn dangle() -> &String { 
    let s = String::from("hello"); 
    &s 
}
  • 同一个作用域内,只允许有一个可变引用或者多个只读引用。
// 这种情况就是你已经被可变应用借用了,在定义只读引用,那就存在问题。
fn main() {
    let mut str1 = String::from("adasdsa");

    let str2 = &mut str1;
    let str3 = &str1;
    str1 += "adad";

    println!("{}", str1);
}

生命周期的概念在后面会讲到,我们先有个概念知道引用的生命周期可以用于实现各种功能,例如:

  • 避免悬垂引用
  • 实现智能指针
  • 实现并发编程

悬垂引用

悬垂引用是指引用指向的值已经被销毁了。悬垂引用会导致程序崩溃。

Rust 的引用机制可以帮助避免悬垂引用。引用的生命周期必须与它引用的值的生命周期相同。因此,如果引用引用的值被销毁了,则引用的生命周期也会结束。

智能指针

智能指针是一种自动管理内存的类型。Rust 提供了一些内置的智能指针,例如 Box、Rc 和 RefCell。 智能指针可以帮助避免悬垂引用。智能指针会在值被销毁时自动释放引用。

并发编程

在并发编程中,多个线程可能同时访问同一个值。如果这些线程都使用引用来访问这个值,则必须确保这些引用的生命周期是安全的。

Rust 的引用机制可以帮助确保引用的生命周期安全。引用的生命周期必须与它引用的值的生命周期相同。因此,如果一个线程正在修改一个值,则其他线程不能使用引用来访问这个值。

参考资料

[1]

google.github.io/comprehensi…: google.github.io/comprehensi…

[2]

跟着谷歌团队学Rust: rexweb.link/category/te…

[3]

梦兽编程: rexweb.link