匹配模式引用或取消引用值之间有什么区别吗? [英] Is there any difference between matching on a reference to a pattern or a dereferenced value?

查看:36
本文介绍了匹配模式引用或取消引用值之间有什么区别吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Clippy 对这样的代码发出警告:

Clippy warns about code like this:

fn func<T>(data: &Option<T>) {
    if let &Some(ref value) = data {}
}

warning: you don't need to add `&` to all patterns
 --> src/main.rs:2:5
  |
2 |     if let &Some(ref value) = data {}
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(match_ref_pats)] on by default
  = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.210/index.html#match_ref_pats
help: instead of prefixing all patterns with `&`, you can dereference the expression
  |
2 |     if let Some(ref value) = *data {}
  |            ^^^^^^^^^^^^^^^   ^^^^^

从编译器的角度来看,这些结构是否相同:

Are these constructions the same from compiler point of view:

if let &Some(ref value) = data {

if let Some(ref value) = *data {

如果是这样,Clippy 消息中有什么意义,只是为了使用统一的样式?

If so, what's the point in the Clippy message, just to use uniform style?

推荐答案

是的,这些对编译器来说是一样的.在这种的情况下,没有太大的好处.真正的好处来自 match 等价物:

Yes, these are the same to the compiler. In this case, there's not much benefit. The real benefit comes from the match equivalent:

fn func(data: &Foo) {
    match data {
        &Foo::One => {}
        &Foo::Two => {}
        &Foo::Three => {}
    }
}

在这里,您只需要在模式中放置一个解引用,而不是 3 个引用:

Here, you only have to place a single dereference, not 3 references in the patterns:

fn func(data: &Foo) {
    match *data {
        Foo::One => {}
        Foo::Two => {}
        Foo::Three => {}
    }
}

从 Rust 1.26 开始,你甚至不必取消引用匹配的表达式:

And since Rust 1.26, you don't even have to dereference the expression being matched on:

fn func(data: &Foo) {
    match data {
        Foo::One => {}
        Foo::Two => {}
        Foo::Three => {}
    }
}

这就是为什么它是惯用的选择.

That's why it's the idiomatic choice.

if let 概念只是此的扩展.

您不能总是取消引用该值.如果您尝试对一对项目执行相同的操作:

You can't always dereference the value. If you tried to do the same thing for a pair of items:

fn func(data: &Foo, data2: &Foo) {
    match (*data, *data2) {
        (Foo::One, _) => {}
        (Foo::Two, _) => {}
        (Foo::Three, _) => {}
    }
}

你得到错误

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:8:12
  |
8 |     match (*data, *data2) {
  |            ^^^^^ cannot move out of borrowed content

在这种情况下,您可以使用参考表格:

In this case, you can use the reference form:

fn func(data: &Foo, data2: &Foo) {
    match (data, data2) {
        (&Foo::One, _) => {}
        (&Foo::Two, _) => {}
        (&Foo::Three, _) => {}
    }
}

或者,从 Rust 1.26 开始,执行一些隐式引用:

Or, since Rust 1.26, perform some implicit references:

fn func(data: &Foo, data2: &Foo) {
    match (data, data2) {
        (Foo::One, x) => {}
        (Foo::Two, _) => {}
        (Foo::Three, _) => {}
    }
}

这篇关于匹配模式引用或取消引用值之间有什么区别吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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