首页 > 解决方案 > 匹配借来的枚举 - 为什么这种语法等效?

问题描述

我有以下代码,它使用 rustc v1.36 编译:

enum Number {
    Integer(i32),
    Real(f32),
}

fn foo1(number: &mut Number) {
    if let Number::Integer(n) = number {
        let _y: &mut i32 = n;
    }
}

fn foo2(number: &mut Number) {
    if let &mut Number::Integer(ref mut n) = number {
        let _y: &mut i32 = n;
    }
}

有趣的是,我可以理解 'foo2' 是如何进行匹配的,但对于 'foo1' 则不然,而 'foo1' 是你在任何 Rust 项目中都会看到的那种代码。有人可以解释这两个中的匹配语法是如何等效的吗?因此它也扩展到其他代码(结构?)?

标签: syntaxrustpattern-matching

解决方案


这个功能是在 Rust 1.26 中添加的,被称为“默认绑定模式”(或“匹配人体工程学”,在提出它的 RFC之后)。它有效地允许模式匹配自动取消引用值,并在需要时添加refref mut到变量绑定。

RFC 中详细讨论了此行为的规则,但实际上可以归结为:

  • 模式中的变量绑定可以通过以下三种模式之一解析:
    • 'move'(默认值),它将移动值。
    • 'ref',它将不可变地引用该值。
    • 'ref mut',它将可变地引用该值。
  • ref当在没有显式, mutor的模式中遇到变量绑定时ref mut,将使用当前绑定模式。
  • 当引用使用非引用模式进行模式匹配时:
    • 该值将自动取消引用。
    • 任何嵌套模式的绑定模式都可能发生变化:
      • 如果引用的类型是&T,则绑定模式将更改为 'ref'。
      • 如果引用的类型是&mut T 并且当前绑定模式不是'ref',则绑定模式将更改为'ref mut'。

这听起来可能很复杂,但正如您从最终结果中看到的那样,它往往与您直观地编写比赛的方式一致!


推荐阅读