nya*_*108 3 pattern-matching mutability rust
我想将my_id
,仅当存在时更改为另一个值:
fn read(id: &mut i32) {
*id = 42;
}
struct S {
my_id: Option<i32>,
}
impl S {
fn run(&mut self) {
match self.my_id {
Some(mut id) => read(&mut id),
_ => (),
}
}
}
fn main() {
let mut s = S { my_id: 0.into() };
s.run();
println!("{:?}", s.my_id);
}
Run Code Online (Sandbox Code Playgroud)
此代码打印Some(0)
,这意味着替换失败,但我不明白为什么。我是否因为模式匹配而失去了可变性?
Shepmaster 的回答和mcarton 的回答很好地解释了您i32
是如何被复制而不是在模式匹配中被引用的。
我想补充一点,该ref
关键字专门用于处理这样的情况,您需要引用而不是模式匹配中的副本:
fn read(id: &mut i32) {
*id = 42;
}
struct S {
my_id: Option<i32>,
}
impl S {
fn run(&mut self) {
match self.my_id {
// `ref` keyword added here
Some(ref mut id) => read(id),
_ => (),
}
}
}
fn main() {
let mut s = S { my_id: 0.into() };
s.run();
println!("{:?}", s.my_id); // prints "Some(42)"
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
当您用my_id
非复制类型替换类型时,问题变得明显:
fn read(_: &mut String) {}
struct S {
my_id: Option<String>,
}
impl S {
fn run(&mut self) {
match self.my_id {
Some(mut id) => read(&mut id),
_ => (),
}
}
}
Run Code Online (Sandbox Code Playgroud)
error[E0507]: cannot move out of `self.my_id.0` which is behind a mutable reference
--> src/lib.rs:9:15
|
9 | match self.my_id {
| ^^^^^^^^^^ help: consider borrowing here: `&self.my_id`
10 | Some(mut id) => read(&mut id),
| ------
| |
| data moved here
| move occurs because `id` has type `std::string::String`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)
Some(mut id)
通过引用确实不匹配:您刚刚制作了该字段的副本。您真正想要的是匹配 on &mut self.my_id
,这mut
在模式中不需要:
match &mut self.my_id {
Some(id) => read(id),
_ => (),
}
Run Code Online (Sandbox Code Playgroud)