匹配模式引用或取消引用值之间有什么区别吗?

2024-05-08

Clippy https://github.com/rust-lang-nursery/rust-clippy对这样的代码发出警告:

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 {}
  |            ^^^^^^^^^^^^^^^   ^^^^^

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

if let &Some(ref value) = data {
if let Some(ref value) = *data {

如果是这样,那么 Clippy 消息中仅仅使用统一的样式有什么意义呢?


是的,这些对于编译器来说是一样的。在this的话,并没有太大的好处。真正的好处来自于match相等的:

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

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

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

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

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

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

The if let概念只是此的延伸。


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

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

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

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

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

fn func(data: &Foo, data2: &Foo) {
    match (data, data2) {
        (Foo::One, x) => {}
        (Foo::Two, _) => {}
        (Foo::Three, _) => {}
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

匹配模式引用或取消引用值之间有什么区别吗? 的相关文章

随机推荐