在此之前,我有一个包含 Sync + Send
特性的 trait,名为 SyncMessenger
:
trait Messenger {
fn send_message(&self, user_id: UserId, text: &str);
}
trait SyncMessenger: Messenger + Sync + Send {}
它的实现:
pub struct DiscordMessenger {
discord: Arc<Discord>, // (Discord is Sync and Send already)
}
impl Messenger for DiscordMessenger {
fn send_message(&self, user_id: UserId, text: &str) {
self.discord.send_message(user_id, text, false);
}
}
impl SyncMessenger for DiscordMessenger {}
并且使用它:
struct Bot {
messenger: Arc<SyncMessenger>,
}
impl Bot {
pub fn new() -> Bot {
Bot { messenger: Arc::new(DiscordMessenger::new()) }
}
fn messenger(&self) -> Arc<SyncMessenger> {
self.messenger.clone()
}
}
struct PingCommand {
fn fire(&mut self, bot: &mut Bot) {
bot.messenger().send_message(UserId(0), "Pong");
}
}
一切正常。现在我想实现TestMessenger
,它不会通过网络发送消息,而是在Self
中切换标志:
#[cfg(test)]
struct TestMessenger {
pub message_sent: bool,
}
impl Messenger for TestMessenger {
fn send_message(&mut self, user_id: UserId, text: &str) { // we have `&mut self` here
self.message_sent = true;
}
}
所以我需要在特征和实现中的每个地方将send_message(&self)
更改为send_message(&mut self)
。我已经这样做了,但之后无法编译我的用户代码:
struct PingCommand {
fn fire(&mut self, bot: &mut Bot) {
bot.messenger().send_message(UserId(0), "Pong");
}
}
错误提示:
|
12 | let _ = bot.messenger().send_message(UserId(0),
| ^^^^^^^^^^^^^^^ cannot borrow as mutable
error: aborting due to previous error
我找到了一种方法,虽然它能够解决问题,但我觉得它非常丑陋(而且使用了
unwrap()
,我希望避免这种情况):let _ = Arc::get_mut(&mut bot.messenger()).unwrap().send_message(UserId(0),
因此,问题在于如何尽可能简单地完成此操作,而不需要使用 unwrap()
或像 Arc::get_mut
这样的静态方法?为什么简单的 fn messenger(&self) -> Arc<SyncMessenger>
无法调用 mut
方法?