在 Rust 中,是否可能取消借用一个可变引用?

8

这里有一个例子

#[derive(Debug)]
struct Point {
    x: Vec<i32>,
    y: i32,
}

let mut p = Point { x: vec![1], y: 7 };

// borrow out mutable reference p to a and b
let Point { x: a, y: b } = &mut p;

// mutate a
a.push(2); 
// how do I get p back?
println!("{:?}", p);

有没有一种方法可以在不创建新的块或将其抽象成函数的情况下取消引用?

1
为什么“不创建新块”?通过在借用之前打开{,并在a.push(2)之后关闭它来创建一个块是(在NLL之前)向Rust发出引用生命周期预期结束的信号的方法。 - Paolo Falabella
2个回答

10

使用Rust 2018。

在具有非词法生命周期(NLL)的Rust 2018中,你的示例是有效的。


您可以通过使用夜间编译器并使用“#![feature(nll)]”来启用NLL,即使您未使用Rust 2018。 - hellow
@hellow,你甚至不需要在夜间版上启用NLL。它默认开启,并在NLL失败时回退到词法生命周期。 - Tim Diekmann

5
你不能这样做。字段xy是(可变)借用的,这意味着Point也是(可变)借用的。所有这些都发生在同一个作用域中,因此Point将保持可变借用状态直到作用域结束,并且你无法在它被可变借用之后访问数据(无论是可变或不可变)。你需要查看内部可变性。使用RefCell<T>
use std::cell::RefCell;

#[derive(Debug)]
struct Point {
    x: RefCell<Vec<i32>>,
    y: i32,
}

fn main() {
    let p = Point {
        x: RefCell::new(vec![1]),
        y: 7,
    };

    (*p.x.borrow_mut()).push(2);

    println!("{:?}", p);
}

编辑1: 根据Yusuke NOJIMA的回答, 是可能的。您需要在使用rust nightly的代码中添加属性#![feature(nll)]

#![feature(nll)]

#[derive(Debug)]
struct Point {
    x: Vec<i32>,
    y: i32,
}

...
...

更多信息,请参考NLL RFC


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接