示例程序:
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\) 个条件时发生:
例如下面的程序时错的:
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)。