Rust 模式匹配如何确定绑定变量是引用还是值? [英] How does Rust pattern matching determine if the bound variable will be a reference or a value?
问题描述
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
是没有意义的;&self
说 self
是一个引用,所以从引用中移出一个值是没有意义的,但是有没有明确定义规则的规范?
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
.
匹配
self
并在每个模式前加上&
以解构"引用.
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. 以上).这就是匹配人体工程学发挥作用的地方:规则说,当引用与非引用模式匹配时,该模式中的绑定通过引用而不是通过值绑定(即,好像它们以 ref为前缀
ref代码>).
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屋!