是的,前者返回实现Iterator<Item = (&usize, &T)> + '_
的类型,而后者返回实现Iterator<Item = &(usize, T)> + '_
的类型.
下面是一个最小的例子:
pub fn iter1(v: &[(usize, i32)]) -> impl Iterator<Item = (&usize, &i32)> + '_ {
v.iter().map(|(key, value)| (key, value))
}
pub fn iter2(v: &[(usize, i32)]) -> impl Iterator<Item = (&usize, &i32)> + '_ {
v.iter()
}
编译失败,并显示以下错误消息:
error[E0271]: expected `std::slice::Iter<'_, (usize, i32)>` to be an iterator that yields `(&usize, &i32)`, but it yields `&(usize, i32)`
--> src/lib.rs:5:37
|
5 | pub fn iter2(v: &[(usize, i32)]) -> impl Iterator<Item = (&usize, &i32)> + '_ {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&(usize, i32)`, found tuple
6 | v.iter()
| -------- return type was inferred to be `std::slice::Iter<'_, (usize, i32)>` here
|
= note: expected reference `&(usize, i32)`
found tuple `(&usize, &i32)`
For more information about this error, try `rustc --explain E0271`.
error: could not compile `playground` due to previous error
Playground.个
前者之所以有效,是因为Rust的模式语法中内置了人体工程学,称为binding modes:
当参考值与非参考模式匹配时,它将被自动视为REF或REF MUT绑定.
所以它基本上是 v.iter().map(|&(ref key, ref value)| (key, value))
的句法糖,这就更清楚地说明了为什么前者有效,而后者不行.