rust - 一个数组如何包含对同一对象的多个可变引用?
问题描述
我正在制作一个基于图块的游戏,其结构跨越多个图块。结构下的每个图块都必须具有对该结构的可变引用。对于跨越两个图块的结构,表示地图的二维数组必须同时包含对该结构的两个可变引用。
我还有一个可变地拥有我所有结构的列表(用于迭代)
我试过这个&mut
但失败了:
let mut all_structures: Vec<Box<Structure>> = Vec::new();
let mut grid: [[Vec<&mut Box<Structure>>; 4]; 4] = Default::default(); // accessed [y][x]
let mut house: Box<Structure> = Box::new(House { });
grid[1][1].push(&mut house);
grid[1][2].push(&mut house);
all_structures.push(house);
有错误:
error[E0499]: cannot borrow `house` as mutable more than once at a time
--> src/main.rs:21:21
|
20 | grid[1][1].push(&mut house);
| ---------- first mutable borrow occurs here
21 | grid[1][2].push(&mut house);
| ---- ^^^^^^^^^^ second mutable borrow occurs here
| |
| first borrow later used by call
现在这只是单线程,所以没有什么需要是线程安全的
我把代码放在操场上
解决方案
最简单的选择是使用Rc<RefCell<Structure>>
而不是Box<Structure>
.
Rc<T>
支持 type 值的共享所有权T
,这使您可以拥有多个指向同一对象的指针,并具有自动生命周期管理。Rc<T>
不是线程安全的;Arc
如果你以后发现你需要线程安全,你可以改为使用。
RefCell<T>
允许您在运行时而不是在编译时强制执行 Rust 借用规则(即,可以有一个&mut
借用或任意数量的借用):这意味着可以有多个路径,您可以通过这些路径潜在地改变同一个对象&
,只要您实际上不这样做。
我在操场上放了一个完整的例子。请注意,这使用.borrow()
and .borrow_mut()
,如果您实际上最终违反了借用规则(例如,通过一次可变地多次借用相同的内容Structure
),它将感到恐慌。
推荐阅读
- python - 线性回归为什么正规方程会给出巨大的误差
- html - XslCompiledTransform 结果不会正确显示在浏览器中
- ios - Swift 协议委托未在 VC 中触发
- versioning - 为什么 NW.js 大版本还是 0?
- javascript - 如何构建一个树形数组,其中/哪些项可以拼接,只允许 1、2、4、8、16 或 32 个项的数组?
- visual-studio - Visual Studio 2019 Live 单元测试崩溃
- python - Tensorflow InvalidArgumentError:断言失败:[标签必须是 <= n_classes - 1]
- c# - 为什么在 C# 中键入 JSON 解析比 node.js JSON.parse 慢得多?
- kotlin - 如何在 FirebaseRecyclerAdapter 中仅向发送者和接收者而不是所有人显示消息布局?
- c# - 在 boostrap 模态中将部分视图作为字符串返回