gpt4 book ai didi

pointers - 引用和框之间的可变性差异

转载 作者:行者123 更新时间:2023-11-29 08:08:03 25 4
gpt4 key购买 nike

我正在尝试了解 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 应该是这样工作的吗?如果是这样,我如何创建指向堆上存储在不可变变量中的可变数据的指针值?

最佳答案

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

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

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

有几种方法可以创建指向堆上可变数据 block 的指针,同时保持指针不可变。最通用的是 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可变内部只是为了保持可变性,你真的不应该。这不是惯用语,只会导致句法和语义负担。

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

事实上,如果你对诸如可变性这样的基本事物有疑问,它可能已经在书中解释过了:)

关于pointers - 引用和框之间的可变性差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31567708/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com