在下面的程序中,我试图理解match当mut, &do come in 时语句的复杂性。除此之外,就任何功能而言没有其他范围。
为了弄清楚变量的类型,我使用变量来调用函数checkout(n:i32)。编译器现在会抱怨 checkout Expects i32,但程序正在传递一些其他类型。我是一个新手,这是我认为我们可以找出我们没有明确提及的变量类型的一种方法。
fn checkout (k5:i32) {}
fn main() {
let k5 = "learning rust".to_string();
let k1 = Some(k5);
match &mut k1 {
Some(mut n) => {
checkout(n);
println!("the idea is {} {} ", n, n);
}
None => {}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我编译程序,会出现以下错误消息
fn checkout (k5:i32) {}
fn main() {
let k5 = "learning rust".to_string();
let k1 = Some(k5);
match &mut k1 {
Some(mut n) => {
checkout(n);
println!("the idea is {} {} ", n, n);
}
None => {}
}
}
Run Code Online (Sandbox Code Playgroud)
上面清楚地表明,当mut n存在于 之内时Some,则发现 的类型n是 的类型String。
但是,如果程序从 变为Some (mut n),Some(n)则 的类型n称为&mut string。通过使用 Some(n) 编译程序可以再次看到这一点,错误消息如下
error[E0308]: mismatched types
--> suds12.rs:9:35
|
9 | Some(mut n)=> {checkout(n);println!("the idea is {} {} ",n,n);},
| ^ expected `i32`, found struct `String`
Run Code Online (Sandbox Code Playgroud)
在这里我们可以很容易地看出它的n类型是&mut String。
为什么会这样呢?
Some(n)为什么绑定但绑定到的n混乱是由于匹配人体工程学的实施方式造成的。&mut StringSome(mut n)nString
在此之前,match参考武器必须更加明确:
let mut k = Some("string".to_string());
match &mut k {
&mut Some(ref mut x) => {},
&mut None => {},
};
Run Code Online (Sandbox Code Playgroud)
使用 1.25.0 或之前的版本进行编译以测试行为
让我们关注所有潜在的绑定x:
x: 将直接绑定到该值,产生一个Stringref x:将通过引用绑定到该值,产生一个&Stringref mut x:将通过可变引用绑定到该值,产生一个&mut Stringmut x: 与 相同x,它会直接绑定到值,产生 a String,唯一的区别是n可以改变可以理解,编写起来很乏味,因此RFC 2005:匹配人体工程学旨在使典型案例更易于使用。为了实现这一点,它引入了绑定模式,如果模式匹配的值是不可变或可变引用,它将自动推断绑定x为ref x或ref mut x。所以上面的代码现在可以写成:
let mut k = Some("string".to_string());
match &mut k {
Some(x) => {},
None => {},
};
Run Code Online (Sandbox Code Playgroud)
好多了。
但是,即使新的绑定模式生效,原始语法仍然存在并且可用。例如,您仍然可以ref在值的绑定中使用仅绑定到其引用。或者,如果您已经匹配可变引用,则可以仅使用ref将绑定覆盖为不可变而不是可变。使用任何ref//ref mut都会mut覆盖绑定模式。
你知道这是怎么回事吗?usingSome(x)将使用ref mut绑定模式,因为它正在 a 上匹配&mut Option<_>,因此绑定x到&mut String。但是使用Some(mut x)绑定模式会被覆盖,因此将直接绑定,并且x是可变的。Stringx
也可以看看: