Früher hatte ich ein Sync + Send
Merkmal SyncMessenger
:Mutable Arc in Rust
trait Messenger {
fn send_message(&self, user_id: UserId, text: &str);
}
trait SyncMessenger: Messenger + Sync + Send {}
Es ist die Implementierung:
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 {}
und deren Verwendung:
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");
}
}
Alles hat gut funktioniert. Jetzt möchte ich TestMessenger
implementieren, die nicht wirklich eine Nachricht über ein Netzwerk senden, sondern schaltet ein Flag in Self
statt:
#[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;
}
}
Also muss ich send_message(&self)
-send_message(&mut self)
überall ändern (in Zügen und in Implementierungen). Ich habe das aber nachdem ich nicht meinen Benutzercode kompilieren können:
struct PingCommand {
fn fire(&mut self, bot: &mut Bot) {
bot.messenger().send_message(UserId(0), "Pong");
}
}
gibt Fehler:
|
12 | let _ = bot.messenger().send_message(UserId(0),
| ^^^^^^^^^^^^^^^ cannot borrow as mutable
error: aborting due to previous error
ich etwas gefunden haben, das funktioniert, aber es sieht sehr hässlich zu mir (und erfordert unwrap()
die ich möchte vermeiden):
let _ = Arc::get_mut(&mut bot.messenger()).unwrap().send_message(UserId(0),
die Frage ist hier, wie dass so viel einfach wie möglich zu machen, ohne unwrap()
s, statische Methoden wie Arc::get_mut
? Warum einfach fn messenger(&self) -> Arc<SyncMessenger>
ist nicht möglich, mut
Methoden aufzurufen?