2014-09-11 1 views
1

В моем коде у меня есть структура, которая хранит сообщения для пользователей в HashMap под названием messages. Внутри функции, которая принимает &mut self в качестве аргумента, когда я нахожу сообщения для пользователя, я хотел бы изменить значение этого поля, чтобы удалить эти сообщения, чтобы пользователь не получал одинаковые сообщения дважды. Тем не менее, я получаю ошибку, что я не могу одолжить себя как изменчивый, потому что я заимствовал его как неизменяемый в начале совпадения шаблонов.изменить поле структуры при сопоставлении с образцом на нем

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

Я нашел этот вопрос modifying a field while pattern matching on it, но принятый ответ на это, кажется, не решить мой вопрос - я не понимаю, как линия &Tokenizer { state: InATag(*) } => { self.state = Outside } самооплодотворения изменяемой снова.

ответ

5

Rust обеспечивает HashMap::pop, чтобы сделать то, что вы хотите легко:

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

Вы на самом деле не изменяя поле в структуры, подбирая на ней, вы соответствия на результат find и пытается изменить базовая хеш-таблица, которую Rust не позволит вам сделать, потому что ссылка message_array больше не будет указывать на действительное местоположение. Можно было бы модифицировать message_array сам, однако с помощью 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 
    }, 
+0

+1 для почти полного согласия. Я просто не знаю, что вы подразумеваете под «ссылкой больше не будет указывать на действительное место». 'find' просто возвращает' Option <&'a V> ', который, возможно, содержит неизменяемую ссылку и по понятным причинам, Rust не позволяет использовать неизменяемую ссылку в качестве изменяемой. – sellibitze

+0

@sellibitze OP хотел изменить хеш-таблицу, а не то, на что указывает 'message_array'. Ссылка, возвращаемая 'find', указывает на хэш-таблицу, поэтому она представляет собой неизменное заимствование хеш-таблицы. 'remove' должен будет сделать (отдельный) изменчивый заимствование, которое средство проверки займа не позволит. Если средство проверки займа не остановило это, тогда 'remove' может уничтожить или изменить местоположение, на которое указывает' message_array', что небезопасно. – wingedsubmariner