在Rust中,结束可变借用有哪些选项?

13

我正在与借用检查器抗争 - 真是奇迹中的奇迹。

虽然我通过添加一个代码块找到了解决方案,但我很好奇是否有其他方法可以结束可变借用,以便下一条语句可以在之后访问绑定。

目前为止,我已经做了这些:

let mut canvas: Canvas = Canvas {
    width: 5,
    height: 5,
    array: vec!['x'; 5*5],
};

{
    let mut renderer: CanvasRenderer = CanvasRenderer::new(&mut canvas);

    renderer.render_point('x', 3, 3);
}

println!("The Value in the array is: {}", canvas.array[9]);

我在绑定一个CanvasRenderer对象后,将其包装在一个块中,在改变画布和作用域结束后,CanvasRenderer会被销毁,我的可变借用canvas现在可以被读取或其他操作。

这种方法是可行的-但现在我想看到其他解决方案!

我听说过drop(stuff),但它并没有像我想象的那样起作用。

1个回答

22

没有其他方法,使用代码块是解决问题的唯一方式。在 Rust 2018 (Rust 1.31 及以后版本)之前,所有借用都是词法作用域,也就是说,它们总是对应于某个词法作用域。唯一大于单个语句的范围是代码块的范围,因此代码块是限制借用范围的唯一工具。

drop() 无法运行有两个原因:第一,因为它需要非词法作用域,而在 Rust 2018 之前不支持;第二,它不能成为管理借用的通用工具:例如,它无法简单地结束一个不可变借用,因为不可变引用是 Copy 类型,无法被“drop”。

另请参见:


因为不可变引用是复制的,你确定不可变引用是复制的吗?所以如果它所引用的值被更改,那么该不可变引用的接收者将不会注意到或无法打印新值?因为它具有复制状态而不是对其的引用?还是我的大脑又失败了? ;) - xetra11
@xetra11,如果你有一个不可变的引用,没有办法通过这个引用或任何其他方式(当然除了unsafe)来改变它所指向的数据。更具体地说,如果你有一个对某个变量的不可变引用,你既不能取得同一变量或其内部的可变引用,也不能直接修改该变量,即使它存储在一个mut插槽中。这是Rust所有权/借用概念的基石之一,也是使不可变引用别名安全的原因之一。另外请注意,可变引用是不可复制的。 - Vladimir Matveev
啊,没错。它说如果有一个可变借用,你就不能有对该值的不可变引用。换句话说,只存在可变引用或值的副本?(除非不安全) - xetra11
@xetra11:一个引用是“Copy”还是不是与底层数据是否为“Copy”无关。不可变引用不会复制底层数据,但引用本身是可复制的(impl Copy for &T)-- 这就是为什么您可以共享不可变引用。另一方面,“&mut T” 引用是不可复制的。 - Daniel
好的,我现在明白了。mut ref永远不会被复制,因为如果它被复制了,两个工作线程就可能会改变其状态。immu ref将复制对底层数据的引用,以便许多工作线程可以读取它们,但由于不可变性,永远不会更改它们。 - xetra11

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