Without a more concrete example, it is hard to tell whether this would solve your problem, but you can use ref
within a match pattern to make a reference to the matched substructure, and you can use ref mut
to make that reference mutable.
So, in your example:
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));
}
or if you need to match other parts of the Tokenizer state, this works too:
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));
}
Note that when doing this sort of code, it can be pretty easy to inadvertently run into borrow-check violations due to aliasing. For example, here is a relatively small change to the second example above that won't compile:
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));
}
causes the following message from 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
because you do not want an outstanding borrow &t
while you are also creating mutable aliases to the internals of t
match
changed recently (or will change, maybe in 0.7). - barjak