假设我有素数和幂的向量:
let mut primes: Vec<usize> = ...;
let mut powers: Vec<u32> = ...;
事实是primes.len() == powers.len()
。
我想向用户返回一个相应功率值为0的素数列表(此代码缺少正确的refs和derefs):
primes.iter().zip(powers)
.filter(|(p, power)| power > 0)
.map(|(p, power)| p)
.collect::<Vec<usize>>()
正如您可能想象的那样,编译器正在抱怨很多。特别是,filter
正在接收类型&(&usize, &u32)
的参数,但我在模式匹配中没有正确地取消引用。我已经尝试了编译器建议的各种模式(例如&(&p, &power)
,这是对我来说最有意义的模式),但没有运气。如何正确执行模式匹配,以便我可以毫无问题地进行power > 0
比较,以便我最终可以收集Vec<usize>
?
答案 0 :(得分:2)
primes.iter().zip(powers)
iter()
按引用进行迭代,因此您可以获得素数的&usize
个元素。 OTOH .zip()
调用.into_iter()
来迭代拥有的值,因此幂是u32
,并且这些迭代器组合迭代(&usize, u32)
。从技术上讲,迭代这种混合类型并没有错,但不一致可能会令人困惑。您可以在素数上使用.into_iter()
或.iter().cloned()
来避免引用,或者调用.zip(powers.iter())
将两者作为参考。
第二件事是.filter()
通过引用&(_,_)
获取项目(因为它只“看到”它们),.map()
通过拥有值(_,_)
(允许它)改变并返回它)。
对于像整数这样的小值,你通常会使用这样的方法:
.filter(|&item| …)
.map(|item| …)
请注意,在闭包中,语法为|pattern: type|
,因此在上面的示例中,&item
等同于:
.filter(|by_ref| {
let item = *by_ref;
})
答案 1 :(得分:1)
有效:
fn main() {
let primes: Vec<usize> = vec![2, 3, 5, 7];
let powers: Vec<u32> = vec![2, 2, 2, 2];
let ret = primes.iter().zip(powers.iter())
.filter_map(|(p, pow)| { // both are refs, so we need to deref
if *pow > 0 {
Some(*p)
} else {
None
}
})
.collect::<Vec<usize>>();
println!("{:?}", ret);
}
请注意,我还使用了powers.iter()
,它通过引用生成元素。您还可以在两个迭代器上使用cloned()
并使用值。