为什么在模式匹配中使用 `ref` 而不是星号? [英] Why is `ref` used instead of an asterisk in pattern matching?

查看:72
本文介绍了为什么在模式匹配中使用 `ref` 而不是星号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解 Rust 中的模式匹配规则.我最初认为模式背后的想法是像这样匹配左侧和右侧:

I am having trouble trying to understand pattern matching rules in Rust. I originally thought that the idea behind patterns are to match the left-hand side and right-hand side like so:

struct S {
    x: i32,
    y: (i32, i32)
}
let S { x: a, y: (b, c) } = S { x: 1, y: (2, 3) }; 
// `a` matches `1`, `(b, c)` matches `(2, 3)`

但是,当我们想要将引用绑定到右侧的值时,我们需要使用 ref 关键字.

However, when we want to bind a reference to a value on the right-hand side, we need to use the ref keyword.

let &(ref a, ref b) = &(3, 4);

这感觉相当不一致.

为什么我们不能像这样使用解引用运算符*来匹配左侧和右侧?

Why can't we use the dereferencing operator * to match the left-hand side and right-hand side like this?

let &(*a, *b) = &(3, 4);
// `*a` matches `3`, `*b` matches `4`

为什么这不是模式在 Rust 中的工作方式?情况并非如此,或者我完全误解了什么?

Why isn't this the way patterns work in Rust? Is there a reason why this isn't the case, or have I totally misunderstood something?

推荐答案

在这种情况下使用 de 引用运算符会非常混乱.ref 有效地引用了该值.这些或多或少是等价的:

Using the dereferencing operator would be very confusing in this case. ref effectively takes a reference to the value. These are more-or-less equivalent:

let bar1 = &42;
let ref bar2 = 42;

注意在 let &(ref a, ref b) = &(3, 4) 中,ab 都是具有 &i32 类型——它们是引用.另请注意,由于匹配人体工程学let (a, b) = &(3, 4) 相同且更短.

Note that in let &(ref a, ref b) = &(3, 4), a and b both have the type &i32 — they are references. Also note that since match ergonomics, let (a, b) = &(3, 4) is the same and shorter.

此外,与号 (&) 和星号 (*) 符号用于类型.正如您所提到的,模式匹配希望将值与模式对齐".&符号已经用于匹配和删除模式中的一层引用:

Furthermore, the ampersand (&) and asterisk (*) symbols are used for types. As you mention, pattern matching wants to "line up" the value with the pattern. The ampersand is already used to match and remove one layer of references in patterns:

let foo: &i32 = &42;

match foo {
    &v => println!("{}", v),
}

以此类推,这种语法的某些变体可能在未来支持原始指针:

By analogy, it's possible that some variant of this syntax might be supported in the future for raw pointers:

let foo: *const i32 = std::ptr::null();

match foo {
    *v => println!("{}", v),
}

因为和号和星号都可以用来删除一层引用/指针,所以它们不能用来添加一层.因此需要一些新的关键字并选择了 ref.

Since both ampersand and asterisk could be used to remove one layer of reference/pointer, they cannot be used to add one layer. Thus some new keyword was needed and ref was chosen.

另见:

这篇关于为什么在模式匹配中使用 `ref` 而不是星号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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