Допустим, у меня есть 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)