来自 Rust 文档:
可变引用有一个很大的限制:对于特定范围内的特定数据,只能有一个可变引用。
文档中的示例确实支持此声明:
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);
但这对我来说有点误导。当最后一行中的 print 语句被删除时,程序可以编译并正常运行(尽管有一些警告)。后来在文档中,他们说这就是 Rust 处理数据竞争的方式。我还没有达到他们解释线程和并行编程的程度,但我想仍然值得问一下在以下情况下我们如何防止数据竞争:
fn main() {
let mut name: String = String::from("Devashish");
// assume that fun1 was called from a new thread
fun1(&mut name);
// fun1 and fun2 are being executed in parallel at this point
fun2(&mut name);
}
fn fun1(re: &mut String) {
println!("From fun1: {}", re);
}
fn fun2(re: &mut String) {
println!("From fun2: {}", re);
}
在上述情况下,我们如何防止数据竞争?
在这种情况下,引用是匿名的。的寿命&mut name
在您的通话中引用fun1
是随附的声明, 那是fun1(&mut name);
.
So 第一个可变引用的生命周期在第二个可变引用开始之前结束.
如果您明确声明了引用,则顺序将确定是否存在冲突(感谢NLL).
这是无效的:
let r1 = &mut name;
let r2 = &mut name;
fun1(r1);
fun2(r2);
这是有效的(使用足够新的 rustc 版本):
let r1 = &mut name;
fun1(r1);
let r2 = &mut name;
fun2(r2);
因为借用检查器可以确定在声明 r2 时不再使用 r1。
如果您尝试在 fun1 后面放置一个新线程,您可能会发现:不,您不能将可变借用从 fun1 内部传递给另一个线程。一旦 fun1 结束,可变借用就会被释放,这在语法上是有保证的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)