Без более конкретного примера, то трудно сказать, будет ли это решить вашу проблему, но вы можете использовать ref
в шаблоне поиска, чтобы сделать ссылку на согласованной подструктуры, и вы можете использовать ref mut
сделать эта ссылка изменчива.
Таким образом, в вашем примере:
enum State { Outside, InATag(~str) }
struct Tokenizer { state: State }
fn main() {
let mut t = Tokenizer { state: InATag(~"foo") };
match t.state {
InATag(ref mut _s) => { *_s = ~"bar"; }
Outside => { /* impossible */ }
}
io::println(fmt!("Hello World: %?", t));
}
или, если вам нужно, чтобы соответствовать другим частям государства Tokenizer, это тоже работает:
fn main() {
let mut t = Tokenizer { state: InATag(~"foo") };
match t {
Tokenizer { state: InATag(ref mut _s) } => { *_s = ~"bar"; }
Tokenizer { state: Outside } => { /* impossible */ }
}
io::println(fmt!("Hello World: %?", t));
}
Обратите внимание, что при выполнении такого рода кода, это может быть довольно легко непреднамеренно привести к нарушениям заимствования из-за сглаживания. Например, здесь относительно небольшое изменение во втором примере выше, что не будет компиляции:
fn main() {
let mut t = Tokenizer { state: InATag(~"foo") };
match &t {
&Tokenizer { state: InATag(ref mut _s) } => { *_s = ~"bar"; }
&Tokenizer { state: Outside } => { /* impossible */ }
}
io::println(fmt!("Hello World: %?", t));
}
вызывает следующее сообщение от rustc:
/tmp/m.rs:7:35: 7:46 error: illegal borrow: creating mutable alias to enum content
/tmp/m.rs:7 &Tokenizer { state: InATag(ref mut _s) } => { *_s = ~"bar"; }
^~~~~~~~~~~
error: aborting due to previous error
, потому что вы не хотите, выдающийся заимствуйте &t
, в то время как вы также создаете изменчивые псевдонимы для внутренних элементов t
какая версия Rust вы используете? – barjak
0,6, почему вы спрашиваете? –
Язык Rust меняется быстро, синтаксис и семантика еще не исправлены. В частности, я уверен, что поведение 'match' изменилось в последнее время (или изменится, возможно, на 0,7). – barjak