【发布时间】:2018-03-23 01:08:18
【问题描述】:
我正在用 Rust 写一个 Rogue-like。我有一个Player,其中有一个Vec 的盒装TimedEffects。定时效果具有activate(&mut Player) 和deactivate(&mut Player) 方法,以及减少剩余时间的tick() 方法。当它变为零时,应该调用deactivate() 方法。
pub struct Player {
timed_effects: Vec<Box<TimedEffect>>,
}
每次玩家移动时,我都需要减少剩余时间。这是在 Player 方法中完成的:
impl Player {
fn regenerate(&mut self) {
self.timed_effects.iter_mut().for_each(|te| te.tick());
for i in 0..self.timed_effects.len() {
if self.timed_effects[i].ticks_remaining() == 0 {
let bte = self.timed_effects.swap_remove(i);
bte.deactivate(self);
}
}
}
}
我最初尝试将self 参数(&mut Player) 传递给TimedEffect 对象的tick() 方法,当时间归零时自动调用deactivate(player) 的逻辑。
对向量的迭代构成对 (Player) self 的借用,这与将 &mut Player 参数传递给 tick() 甚至与 .filter 进行单独迭代不兼容。
相反,如图所示,我发现自己在一个整数范围内进行迭代,将框从向量中提取到一个局部变量中,然后对其调用 .deactivate(self)。
这很痛苦。
鉴于效果需要与其受害者建立某种联系,以便deactivate() 方法可以撤消效果,我应该如何构建这些对象,以免我陷入这个依赖借用网络中?
【问题讨论】:
-
请提供minimal reproducible example。我的猜测是,您在某处遇到了一些编译器错误,可以将您指向合适的现有问答,但我们看不到错误是什么。缺少 MCVE 还意味着我们必须重新键入所有依赖代码,这可能会引入令人兴奋的新错误。
-
话虽如此,使用我的推理能力,我猜它是How can I call a mutating method while holding a reference to self?、Passing mutable self reference to method of owned object 或cannot borrow
self.xas immutable because*selfis also borrowed as mutable 中的一个或多个的副本。请继续edit您的问题,以解释为什么这些问题没有回答或将问题标记为重复。 -
我正在学习 Rust - 我到处都是编译器错误!但是我遵循了这些错误,并生成了显示的代码,通过不使用 rust 的迭代器来避免借用。我的问题实际上是关于设计的,哪些设计更改可以产生更好的结果。 (我没有错误的事实可能阻碍了我的搜索,因为我没有正确的关键字......)
-
Rust 正在保护你未来的自己免于在脚下开枪。想象一下迭代
.tick(&mut player)现在可以工作了。如果将来您决定添加一个定时效果,在.deactivate()上移除播放器的所有其他定时效果怎么办?你最终会得到一个无效的迭代器。强迫你采用的设计锈没有那个问题。
标签: rust