Rust中的可变引用(存在一些问题)

示例程序:

fn main() {
    let mut s = String::from("hello");
    make_yuyoubei(&mut s);
    println!("{}", s);  // 输出 yuyoubei
}

fn make_yuyoubei(s: &mut String) {
    *s = String::from("yuyoubei");
}

使用使用 &mut 来修饰函数调用时的可变引用;函数声明时也需要 &mut 来修饰函数类型。

不能在同一作用域中对同一个变量声明两个或多个可变引用

例如下面的程序是错误的:

fn main() {
    let mut s = String::from("yuyoubei");

    let r1 = &mut s;
    let r2 = &mut s;

    println!("r1 = {}, r2 = {}", r1, r2);
}

会提示出错:

error[E0499]: cannot borrow `s` as mutable more than once at a time 
 --> src\main.rs:5:14
  |
4 |     let r1 = &mut s;
  |              ------ first mutable borrow occurs here
5 |     let r2 = &mut s;
  |              ^^^^^^ second mutable borrow occurs here
6 | 
7 |     println!("r1 = {}, r2 = {}", r1, r2);
  |                                  -- first borrow later used here

在Rust中使用这条限制性规则(即同一作用域中不能对同一变量声明两个可变引用)可以有效避免数据竞争。

数据竞争(data race) 会在指令满足如下 \(3\) 个条件时发生:

  1. 两个或两个以上的指针同时访问同一空间;
  2. 其中至少有一个指针会向空间中写入数据;
  3. 没有同步数据访问的机制。

不能在拥有不可变引用的同时创建可变引用

例如下面的程序时错的:

fn main() {
    let mut s = String::from("yuyoubei");

    let r1 = &s;
    println!("r1 = {}", r1);    // 正确,输出 r1 = yuyoubei
    
    let r2 = &s;
    println!("r2 = {}", r2);    // 正确,输出 r2 = yuyoubei

    let r3 = &mut s;
    println!("r3 = {}", r3);    // 错误!
}

一些问题

虽然书上说有问题,但是实际我是可以正常运行的,运行结果:

r1 = yuyoubei
r2 = yuyoubei
r3 = yuyoubei

也就是说我这个程序不光能编译,还能够正常运行。也就是说程序原本第11行注释“错误!”前面地内容,我是能够正确运行的。

所以我也不确定 不能在拥有不可变引用的同时创建可变引用 这一点目前是否仍然成立。因为书本对应的Rust版本是Rust 2018,而我使用的Rust版本是 Rust 1.58.0(Rust 2021)。

posted @ 2022-01-26 22:51  鱼又悲  阅读(390)  评论(1编辑  收藏  举报