我正在制作一个机器人。当机器人收到消息时,它需要检查所有命令是否触发了消息,如果是,则执行操作。
所以我在主结构中有一个命令向量(Command
trait):
struct Bot {
cmds: Vec<Box<Command>>,
}
一切都很好,直到我尝试列出触发命令并稍后在 (&self mut)
方法中使用它们:
let mut triggered: Vec<Box<command::Command>>;
for c in &self.cmds {
if c.check(&message) {
triggered.push(c.clone());
}
}
错误:
bot.rs:167:44: 167:56 error: mismatched types:
expected `Box<Command>`,
found `&Box<Command>`
(expected box,
found &-ptr) [E0308]
我在这里做错了什么?我尝试了很多但没有任何帮助。 最初我在做以下事情:
for c in &self.cmds {
if c.check(&message) {
c.fire(&message, self);
}
}
但它给了我:
bot.rs:172:46: 172:50 error: cannot borrow `*self` as mutable because `self.cmds` is also borrowed as immutable [E0502]
bot.rs:172
c.fire(&message, self);
所以我stackoverflowed它并得出上面的解决方案。
最佳答案
What am I doing wrong here? I tried a lot but nothing helps. Initially I was doing the following:
for c in &self.cmds { if c.check(&message) { c.fire(&message, self); } }
如果 fire
函数不需要访问其他命令,一个选项是暂时用空向量替换 self.cmd
:
trait Command {
fn check(&self, message: &str) -> bool;
fn fire(&mut self, bot: &Bot);
}
struct Bot {
cmds: Vec<Box<Command>>,
}
impl Bot {
fn test(&mut self, message: &str) {
use std::mem;
// replace self.cmds with a empty vector and returns the
// replaced vector
let mut cmds = mem::replace(&mut self.cmds, Vec::default());
for c in &mut cmds {
if c.check(message) {
c.fire(self);
}
}
// put back cmds in self.cmds
mem::replace(&mut self.cmds, cmds);
}
}
有other answers使用这种方法的。
如果 fire
确实需要访问 Bot
的某些字段,您可以只传递需要的字段而不是 self
:
c.fire(self.others)
关于vector - 如何从另一个矢量制作盒装特征对象的矢量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37509459/