rust - 如何处理相互依赖的 Rust 借用?

标签 rust

我正在用 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) 传递给 TimedEffecttick() 方法> 对象,具有在时间归零时自动调用 deactivate(player) 的逻辑。

迭代向量构成了对 (Player) self 的借用,这与将 &mut Player 参数传递给 不兼容tick(),甚至使用 .filter 进行单独的迭代。

相反,如图所示,我发现自己迭代了一个整数范围,将框从向量中提取到局部变量中,然后对其调用 .deactivate(self)

这很痛苦。

考虑到效果需要与其受害者有某种联系,以便 deactivate() 方法可以撤消效果,我应该如何构建这些对象,这样我才不会纠结于此依赖借用网络?

最佳答案

为了避免借用问题,您可以分两步进行:

  1. 将完成的效果从 timed_effects 转移到缓冲区,
  2. 迭代缓冲区并调用deactivate

我将使用 nightly 的 Vec::drain_filter对于更流畅的代码,虽然它肯定不是强制性的。

fn regenerate(&mut self) {
    self.timed_effects.iter_mut().for_each(|te| te.tick());

    let timed_out: Vec<_> =
        self.timed_effects
            .drain_filter(|t| t.ticks_remaining() == 0)
            .collect();

    //  Split iteration in a second step to stop borrowing self.
    for timer in timed_out {
        timer.deactivate(self);
    }
}

为了进一步提高效率,您可以将可重用缓冲区传递给 regenerate(以避免分配)。

关于rust - 如何处理相互依赖的 Rust 借用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49440876/

相关文章:

types - 使用 nom 解析字面量和返回值

rust - 为什么AtomicUsize的fetch_max返回的值大于其参数?

url - `web_sys::Url::create_object_url_with_blob(&blob)` 未正确格式化二进制数据

rust - 为 Iterator::find 提供闭包时的值和引用

rust - 有没有办法在 Rust 中将类型标记为不可丢弃?

algorithm - 如何检查向量是否是另一个向量的子序列(顺序相同但不连续)?

arrays - 使用 const 泛型将可变指针数组转换为可变引用

arrays - 在 Rust 中,当其他字符不感知时,将字符串拆分为 Vec<String> 字符的最佳方法?

rust - 如何在 Rust 的语句中使用 std::convert::Into?

rust - 如何将一个枚举分成两部分放在不同的 crate 中?