【发布时间】:2021-10-10 14:30:31
【问题描述】:
下面的sn-p不能编译
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 的sn-p 也会编译
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 并在第一个 sn-p 中取消引用它?
【问题讨论】:
-
rand 生成器不产生引用,而是产生 u8。元组的取消引用是自动的。没有理由使用 &,也没有使用 *(即使在第二个 sn-p 中)。
-
@Stargateur 好的,我明白了...但是为什么
.filter(|(_, x)| *x % 2 == 1)有效?模式匹配如何将&(usize, u8)类型的内容应用到(_, x)?
标签: types rust pattern-matching type-inference type-mismatch