匹配模式引用或取消引用值之间有什么区别吗?
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, _) => {}
}
}