1
votes

In my code, I have a struct which stores messages for users in a HashMap called messages. Inside a function which takes &mut self as an arguement, when I find messages for the user, I would like to modify the value of this field to remove these messages, so that the user doesn't get the same messages twice. However, I get the error that I can't borrow self as mutable because I've borrowed it as immutable at the start of the pattern match.

match self.messages.find(&username) {
             Some(message_array) => {
               //do some stuff to send the messages
               self.messages.remove(&username);
             },

I found this question modifying a field while pattern matching on it, but the accepted answer for it doesn't seem to address my question -- I don't understand how the line &Tokenizer { state: InATag(*) } => { self.state = Outside } makes self mutable again.

1

1 Answers

5
votes

Rust provides HashMap::pop to make what you want easy:

match self.messages.pop(&username) {
    Some(message_array) => {
        // do some stuff to send the messages
        // entry for &username is already removed
    },

You aren't really modifying a field of a struct while matching on it, you're matching on the result of find and trying to modify the underlying hashtable, which Rust won't let you do because then the message_array reference wouldn't point to a valid location anymore. It would be possible to modify message_array itself however using find_mut:

match self.messages.find_mut(&username) {
    Some(message_array) => {
        // do some stuff to send the messages
        message_array.truncate(0) // remove all messages
    },