在匹配可变引用时,“mut”如何工作?

Sud*_*san 8 match rust

在下面的程序中,我试图理解matchmut, &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

为什么会这样呢?

kmd*_*eko 6

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: 将直接绑定到该值,产生一个String
  • ref x:将通过引用绑定到该值,产生一个&String
  • ref mut x:将通过可变引用绑定到该值,产生一个&mut String
  • mut x: 与 相同x,它会直接绑定到值,产生 a String,唯一的区别是n可以改变

可以理解,编写起来很乏味,因此RFC 2005:匹配人体工程学旨在使典型案例更易于使用。为了实现这一点,它引入了绑定模式,如果模式匹配的值是不可变或可变引用,它将自动推断绑定xref xref 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

也可以看看: