我们可以在同一范围内对同一数据有多个可变引用,不是吗?

时间:2019-07-16 10:43:54

标签: rust

来自Rust文档:

  

可变引用有一个很大的限制:您只能对一个特定范围内的特定数据进行一个可变引用。

文档中的示例确实支持以下语句:

let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);

但这对我有点误导。删除最后一行中的print语句后,程序将编译并运行正常(尽管有一些警告)。后来在文档中,他们说这是锈处理数据竞争的方式。我还没有到达他们解释线程和并行编程的地步,但我认为仍然值得问一下在以下情况下如何防止数据争用:

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);
}

在上述情况下,我们如何防止数据争用?

1 个答案:

答案 0 :(得分:2)

在这种情况下,引用是匿名的。您对@FindBy(xpath = "//div[@class='form_control ng-binding' and @title='Low'][contains(@ng-bind, 'customerSegmentation')]") WebElement Customer; is the enclosing statement的调用中&mut name引用的生存期,即fun1

因此第一个可变引用的生存期在第二个可变引用开始之前结束

如果您明确声明了引用,则该顺序将确定是否存在冲突(由于NLL)。

这是无效的:

fun1(&mut name);

这是有效的(使用最新版本的rustc):

let r1 = &mut name;
let r2 = &mut name;
fun1(r1);
fun2(r2);

因为借用检查器可以确定在声明r2时不再使用r1。

您可能会发现是否尝试在fun1后面放置新线程:不,您无法将可变借项从fun1内部传递给另一个线程。 fun1结束后,就释放了可变借位,从语法上保证了这一点。