如果没有更具体的示例,很难判断这是否会解决您的问题,但您可以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