【问题标题】:Difference in mutability between reference and box参考和盒子之间的可变性差异
【发布时间】:2015-10-12 14:21:59
【问题描述】:

我试图理解 Rust 指针类型及其与可变性的关系。具体来说,声明一个持有指针且自身可变的变量的方法——即可以指向其他内存,并声明数据本身是可变的——即可以改变通过指针变量的值。

这就是我理解普通引用的工作方式:

let mut a = &5; // a is a mutable pointer to immutable data
let b = &mut 5; // b is an immutable pointer to mutable data

所以a 可以更改为指向别的东西,而b 不能。但是b指向的数据可以通过b改变,而不能通过a改变。 我理解正确吗?

对于问题的第二部分——为什么Box::new 的行为似乎不同?这是我目前的理解:

let mut a = Box::new(5); // a is a mutable pointer to mutable data
let c = Box::new(7); // c is an immutable pointer to immutable data

new 应该返回一个指向一些堆分配数据的指针,但它指向的数据似乎从持有指针的变量继承了可变性,这与示例中这两种可变性状态是独立的引用不同! Box::new 应该是这样工作的吗?如果是这样,我如何创建指向存储在不可变变量中的堆上​​可变数据的指针值?

【问题讨论】:

    标签: pointers reference rust immutability


    【解决方案1】:

    首先,您确实了解引用的正确行为方式。 mut a 是一个可变变量(或者,更准确地说,一个可变绑定),而 &mut 5 是一个可变引用,指向一个可变数据(它被隐式分配在堆栈上)。

    其次,Box 的行为与引用不同,因为它与引用根本不同Box 的另一个名称是拥有/拥有的指针。每个Box 拥有它持有的数据,并且它唯一地这样做,因此这些数据的可变性继承自盒子本身的可变性。所以是的,这正是Box 的工作方式。

    另一种可能更实用的理解它的方法是认为Box<T> 完全等同于T,除了固定大小和分配方法。换句话说,Box 提供了值语义:它像任何值一样被移动,它的可变性取决于它所存储的绑定。

    有几种方法可以在堆上创建指向可变数据的指针,同时保持指针不可变。最通用的是RefCell

    use std::cell::RefCell;
    
    struct X { id: u32 }
    let x: Box<RefCell<X>> = Box::new(RefCell::new(X { id: 0 }));
    x.borrow_mut().id = 1;
    

    或者,您可以使用Cell(对于Copy 类型):

    let x: Box<Cell<u32>> = Box::new(Cell::new(0));
    x.set(1);
    

    请注意,上述示例使用了所谓的“内部可变性”,除非您确实需要它,否则最好避免使用它。如果你想创建一个内部可变的Box 只是为了保持可变性属性,你真的不应该。它不是惯用的,只会导致句法和语义负担。

    您可以在这里找到很多有用的信息:

    事实上,如果你对可变性等基本问题有疑问,书中可能已经解释过了:)

    【讨论】:

    • 谢谢你的回答,我还在处理它,但我刚刚问了另一个类似的问题,你可能会回答:stackoverflow.com/questions/31568177/…
    • @jco,关于您的编辑。 &amp;mut 引用不拥有数据。 &amp;&amp;mut 的引用通常被称为借用,这是有原因的。 &amp;mut 唯一借用数据,但不拥有它。
    • 好的,谢谢。借用只是为了将所有权归还给前一个/调用所有者的语法糖吗?
    • 没有。借贷正是它作为常规词的含义——它是一种在不放弃所有权的情况下向其他人提供对您拥有的价值的访问权的方式。借用是通过引用实现的。您可以在 Rust 官方书籍中找到很好的解释 - 答案中提供了相应的链接。
    • 好的,那么我们可以说借用是通过引用在编译器中“硬编码”的,与所有权不同吗?
    猜你喜欢
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多