与“.enumerate()”不匹配的类型:预期类型“u8”,找到引用“&_”
Mismatched types with `.enumerate()`: expected type `u8`, found reference `&_`
以下代码段无法编译
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let indices_of_odd_numbers = (1..100)
.map(|_| rng.gen::<u8>())
.enumerate()
.filter(|(_, &x)| x % 2 == 1)
.map(|(i, _)| i)
.collect::<Vec<_>>();
println!("{:?}", &indices_of_odd_numbers);
}
错误信息为
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:9:22
|
9 | .filter(|(_, &x)| x % 2 == 1)
| ^^- expected due to this
| |
| expected `u8`, found reference
| help: you can probably remove the explicit borrow: `x`
|
= note: expected type `u8`
found reference `&_`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
然而,当我将.filter(|(_, &x)| x % 2 == 1)
替换为.filter(|(_, x)| *x % 2 == 1)
时,它编译顺利。此外,一旦我摆脱了 .enumerate()
,以下使用模式匹配将 x
隐含地推向 u8
的代码片段也会编译
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let odd_numbers = (1..100)
.map(|_| rng.gen::<u8>())
.filter(|&x| x % 2 == 1)
.collect::<Vec<_>>();
println!("{:?}", &odd_numbers);
}
我无法理解为什么模式匹配不适用于 .enumerate()
。为什么编译器不能推断 x
应该是 u8
并在第一个片段中取消引用它?
enumerate()
创建一个元组,在你的情况下 (usize, u8)
,filter()
通过引用发送 Iterator
的 Item
,所以 &(usize, u8)
不是 (&usize, &u8)
。所以 |(_, &x)|
没有意义,因为你试图取消引用 u8
的编译器。你可以做的是 |&(_, x)|
但编译器又一次足够聪明,建议简单地删除 &x
的 &
并且你的原始文件会编译。
.filter(|(_, x)| *x % 2 == 1)
比较复杂,|(_, x)|
可以写成|(_, ref x)|
&x
的倒数,意思是参考x
。所以在这里编译器自动添加 ref
关键字,然后你只需取消引用 x
即可。它更明确但不需要。
有关 RFC 2005 and binding modes
的更多信息
以下代码段无法编译
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let indices_of_odd_numbers = (1..100)
.map(|_| rng.gen::<u8>())
.enumerate()
.filter(|(_, &x)| x % 2 == 1)
.map(|(i, _)| i)
.collect::<Vec<_>>();
println!("{:?}", &indices_of_odd_numbers);
}
错误信息为
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:9:22
|
9 | .filter(|(_, &x)| x % 2 == 1)
| ^^- expected due to this
| |
| expected `u8`, found reference
| help: you can probably remove the explicit borrow: `x`
|
= note: expected type `u8`
found reference `&_`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
然而,当我将.filter(|(_, &x)| x % 2 == 1)
替换为.filter(|(_, x)| *x % 2 == 1)
时,它编译顺利。此外,一旦我摆脱了 .enumerate()
,以下使用模式匹配将 x
隐含地推向 u8
的代码片段也会编译
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let odd_numbers = (1..100)
.map(|_| rng.gen::<u8>())
.filter(|&x| x % 2 == 1)
.collect::<Vec<_>>();
println!("{:?}", &odd_numbers);
}
我无法理解为什么模式匹配不适用于 .enumerate()
。为什么编译器不能推断 x
应该是 u8
并在第一个片段中取消引用它?
enumerate()
创建一个元组,在你的情况下 (usize, u8)
,filter()
通过引用发送 Iterator
的 Item
,所以 &(usize, u8)
不是 (&usize, &u8)
。所以 |(_, &x)|
没有意义,因为你试图取消引用 u8
的编译器。你可以做的是 |&(_, x)|
但编译器又一次足够聪明,建议简单地删除 &x
的 &
并且你的原始文件会编译。
.filter(|(_, x)| *x % 2 == 1)
比较复杂,|(_, x)|
可以写成|(_, ref x)|
&x
的倒数,意思是参考x
。所以在这里编译器自动添加 ref
关键字,然后你只需取消引用 x
即可。它更明确但不需要。
有关 RFC 2005 and binding modes
的更多信息