Сопоставление с образцом в ржавчине и изменчивости - PullRequest
1 голос
/ 02 марта 2020

Допустим, у меня есть Option<String> и я хочу сопоставить с шаблоном, чтобы получить изменяемую ссылку на String. Я могу сделать следующее (_a должен быть изменяемым):

  let mut _a: Option<String> = Some(String::from("foo"));
  if let Some(ref mut aa) = _a {
    aa.push_str("_");
    println!("aa: {:?}", aa)
  }

Теперь предположим, что у меня есть два Option<String> значения, которые я хочу сопоставить с образцом.

  let _b: Option<String> = Some(String::from("bar"));
  let _c: Option<String> = Some(String::from("baz"));
  if let (Some(ref mut bb), Some(ref mut cc)) = (_b, _c) {
    bb.push_str("_");
    cc.push_str("_");
    println!("bb: {:?}, cc: {:?}", bb, cc);
  }

Странно, я могу использовать ref mut в шаблонах, даже если ни _b, ни _c не являются изменяемыми, и я могу изменять строки. Почему это разрешено здесь в этом случае? Я ожидал бы, что это не скомпилируется, если только _b и _c не объявлены как изменяемые, как в первом примере выше.

Я думаю, что может происходить то, что в сопоставлении с образцом создается кортеж т. е. (_b, _c), а затем некоторые волхвы компилятора c допускают ref mut на паттерне, который "привязан" к этому кортежу. Это правильно?

Версия Rust:

rustc 1.41.1 (f3e1a954d 2020-02-24)

1 Ответ

2 голосов
/ 02 марта 2020

mut не требуется, если значение заключено в кортеж, поскольку кортеж является новым значением ( детская площадка ):

let a = Some(String::from("foo"));
if let (Some(mut aa),) = (a,) {
    aa.push_str("_");
    println!("aa: {:?}", aa)
}
...