我花了一些时间用 Rust 开发一个新项目。
我无法理解我是否以正确的方式使用 Cell。 这是我目前的问题,很普遍。
我需要访问 struct World,它拥有某些资源的所有权。 特别是我需要(mut)对资源的引用。当我需要对资源进行可变访问(需要 &mut World)和非 mut 引用(需要 &World)时,就会出现问题。我无法将此类引用放在一起,因为这会违反 Rust 的引用规则。
我想解决这个问题的方法是使用单元格。 我的项目中有这段代码:
fn take_world(&self, func: impl FnOnce(World) -> World) {
let state = self.state_ref();
let world = state.world
.take();
let world = func(world);
state.world
.replace(world);
}
这应该让我从单元格中取出世界,使用 FnOnce 执行我需要的操作,然后自动替换它。
您认为这是一个好方法吗?这可以被认为是代码异味吗?
其他解决方案可能包括代码重构,但世界/资源部分来自库,所以我对此无能为力。
这本身并不是代码味道。
Cell
旨在提供内部可变性,无需内存开销,但它是通过禁止对其内容进行引用访问来实现的,并且不能跨线程使用。因此,实际上,您只能通过转移所有权(或 Cell
-ing)来获取和设置 Copy
中的值。因此,这不仅不是代码味道,而且几乎是根据先前值更新 Cell
中的值的唯一方法。将其包装在函数中只是一个自然的扩展。甚至还有即将稳定的 .update()
方法可以大致为您完成此操作(尽管它依赖于 Copy
而不是填写 Default
)。
使用
Cell
来操作你的 World
是否有代码味道将取决于你的设计的其余部分,并且会偏离基于意见的方向。您已经标记了 Bevy,它提供了多种使用实体和组件的方法,因此我觉得可能有一种方法可以在没有内部可变性的情况下完成您想做的事情,但这只是猜测。