首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么filter()对并行迭代器有不同的类型要求?

为什么filter()对并行迭代器有不同的类型要求?
EN

Stack Overflow用户
提问于 2021-03-17 04:15:25
回答 1查看 294关注 0票数 3

我试图理解为什么不需要指定正确的类型就不能工作,而如果我不使用并行迭代器,filter()将正确工作。这是我的密码:

代码语言:javascript
复制
use rayon::prelude::*;

fn is_even(n: i64) -> bool {
    n % 2 == 0
}

fn main() {
    let v: Vec<_> = (1..300_000_000)
        .into_par_iter()  //  works correctly without this line, but not parallel
        .filter(|&x| is_even(x))
        .collect();
}

以下是错误消息:

代码语言:javascript
复制
error[E0271]: type mismatch resolving `<rayon::range::Iter<i32> as rayon::iter::ParallelIterator>::Item == i64`
  --> src/main.rs:11:10
   |
11 |         .filter(|&x| is_even(x))
   |          ^^^^^^ expected `i32`, found `i64`

error[E0271]: type mismatch resolving `<rayon::range::Iter<i32> as rayon::iter::ParallelIterator>::Item == i64`
  --> src/main.rs:12:10
   |
12 |         .collect();
   |          ^^^^^^^ expected `i32`, found `i64`
   |
   = note: required because of the requirements on the impl of `rayon::iter::ParallelIterator` for `rayon::iter::Filter<rayon::range::Iter<i32>, [closure@src/main.rs:11:17: 11:32]>`

如果我不使用filter(),为什么into_par_iter()只在不指定整数类型的情况下工作?(我知道我可以通过将范围标记为i64来修复它,但不知道为什么需要这样做)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-17 06:08:07

更新:这种类型的推断问题在人造丝1.5.1中是https://github.com/rayon-rs/rayon/pull/834

为什么真的..。深入研究它,这是因为人造丝决定了Range是否实现了IntoParallelIterator

代码语言:javascript
复制
impl<T> IntoParallelIterator for Range<T> where Iter<T>: ParallelIterator { ... }

struct Iter<T> {
    range: Range<T>,
}

impl ParallelIterator for Iter<u8> { type Item = u8; }
impl ParallelIterator for Iter<u16> { type Item = u16; }
impl ParallelIterator for Iter<u32> { type Item = u32; }
impl ParallelIterator for Iter<u64> { type Item = u64; }
impl ParallelIterator for Iter<i8> { type Item = i8; }
impl ParallelIterator for Iter<i16> { type Item = i16; }
impl ParallelIterator for Iter<i32> { type Item = i32; }
impl ParallelIterator for Iter<i64> { type Item = i64; }
// etc

编译器正在试图查看(1..300_000_000).into_par_iter()是否合法,而且由于ParallelIterator是为Iter<T>类型单独实现的,所以它被迫在进行T之前推断出T是什么。

请参阅游乐场上的非工作重建。

如果他们做了这样的事情:

代码语言:javascript
复制
impl<T> ParallelIterator for Iter<T> where T: SomeIntegerType + Send {
    type Item = T;
}

trait SomeIntegerType {}
impl SomeIntegerType for u8 {}
impl SomeIntegerType for u16 {}
impl SomeIntegerType for u32 {}
impl SomeIntegerType for u64 {}
impl SomeIntegerType for i8 {}
impl SomeIntegerType for i16 {}
impl SomeIntegerType for i32 {}
impl SomeIntegerType for i64 {}
// etc

编译器可以看到Iter实现了ParallelIterator,只要T实现了SomeIntegerType,但是它现在不需要推断类型,它可以等到以后。

看看我在游乐场上的工作重建。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66666909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档