Rust 模式匹配如何确定绑定变量是引用还是值? [英] How does Rust pattern matching determine if the bound variable will be a reference or a value?

查看:54
本文介绍了Rust 模式匹配如何确定绑定变量是引用还是值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

use crate::List::{Cons, Nil};

#[derive(Debug)]
struct Foo {}

#[derive(Debug)]
enum List {
    Cons(i32, Foo),
    Nil,
}

impl List {
    fn tail(&self) -> Option<&Foo> {
        match self {
            Cons(_, item) => Some(item), // why `item` is of type `&Foo`?
            Nil => None,
        }
    }
}

如评论中所述,为什么 item&Foo 类型?item 的类型是 &Foo 而不是 Foo 的规则是什么?

As stated in the comment, why is item of type &Foo? What is the rule that says item will be type &Foo rather than Foo?

我知道将 item 设为 Foo 是没有意义的;&selfself 是一个引用,所以从引用中移出一个值是没有意义的,但是有没有明确定义规则的规范?

I understand that it does not make sense for item to be Foo; &self says self is a reference, so it does not make sense to move a value out of a reference, but are there any specifications that define the rules clearly?

推荐答案

RFC 2005(又名匹配人体工程学)引入了该规则.

RFC 2005 (a.k.a. match ergonomics) introduced the rule.

在实施更改之前,有两种方法可以编写此match.

Before the change was implemented, there were 2 ways to write this match.

  1. 匹配 self 并在每个模式前加上 & 以解构"引用.

  1. Match on self and prefix each pattern with & to "destructure" the reference.

fn tail(&self) -> Option<&Foo> {
    match self {
        &Cons(_, ref item) => Some(item),
        &Nil => None,
    }
}

  • 匹配 *self 并且不要在每个模式前加上 &(因为 *self 不是引用).

  • Match on *self and don't prefix each pattern with & (because *self is not a reference).

    fn tail(&self) -> Option<&Foo> {
        match *self {
            Cons(_, ref item) => Some(item),
            Nil => None,
        }
    }
    

  • 然而,在这两种情况下,我们都需要编写ref item,否则我们会得到error[E0507]: cannot move out of Bored content.

    Yet, in both cases, we need to write ref item, otherwise we'll get error[E0507]: cannot move out of borrowed content.

    然而,在您编写的 match 中,被匹配的表达式是一个引用(类型 &List),但模式不是引用模式(如1. 以上).这就是匹配人体工程学发挥作用的地方:规则说,当引用与非引用模式匹配时,该模式中的绑定通过引用而不是通过值绑定(即,好像它们以 refref).

    However, in the match you've written, the expression being matched is a reference (type &List) but the patterns are not reference patterns (as in 1. above). This is where match ergonomics kick in: the rule says that when a reference is matched with a non-reference pattern, the bindings within that pattern bind by reference rather than by value (i.e. as if they were prefixed with ref).

    这篇关于Rust 模式匹配如何确定绑定变量是引用还是值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆