意外的"method not found"编译器错误



这个问题源于我(在学习Rust的玩具项目中(使用itertoolscartesian_product和Rayon的into_par_iter。我的问题不是关于这个特定的代码,而是关于阅读rustc错误消息和Rust库文档的问题。

如预期:

fn main() {
let it = 0..15;
it.into_par_iter().for_each(|x| println!("{:?}", x));
}

但是下面的代码未能编译,并显示错误。cartesian_product返回的Product的文档包括Iterator的实现,所以我本以为into_par_iter方法调用会进行类型检查,但事实并非如此。

以下是失败代码和由此产生的错误消息:

fn main() {
let it = (0..15).cartesian_product(0..8);
it.into_par_iter().for_each(|x| println!("{:?}", x));
}
Compiling iters v0.1.0 (D:rustiters)
error[E0599]: no method named `into_par_iter` found for struct `itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>` in the current scope
--> srcmain.rs:8:8
|
8   |       it.into_par_iter().for_each(|x| println!("{:?}", x));
|          ^^^^^^^^^^^^^ method not found in `itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>`
|
::: D:rustdot.cargoregistrysrcgithub.com-1ecc6299db9ec823itertools-0.9.0srcadaptorsmod.rs:288:1
|
288 | / pub struct Product<I, J>
289 | |     where I: Iterator
290 | | {
291 | |     a: I,
...   |
294 | |     b_orig: J,
295 | | }
| | -
| | |
| |_doesn't satisfy `_: rayon::iter::IntoParallelIterator`
|   doesn't satisfy `_: rayon::iter::ParallelIterator`
|
= note: the method `into_par_iter` exists but the following trait bounds were not satisfied:
`itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>: rayon::iter::ParallelIterator`
which is required by `itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>: rayon::iter::IntoParallelIterator`
`&itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>: rayon::iter::ParallelIterator`
which is required by `&itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>: rayon::iter::IntoParallelIterator`
`&mut itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>: rayon::iter::ParallelIterator`
which is required by `&mut itertools::adaptors::Product<std::ops::Range<{integer}>, std::ops::Range<{integer}>>: rayon::iter::IntoParallelIterator`

itertools::Itertools::cartesian_product返回类型为itertools::Product的值,该值实现std的Iterator

然而,Rayon不能只处理任何实现Iterator的类型,它还必须实现rayon::ParallelIterator。Rayon恰好为大多数std迭代器提供了ParallelIterator的实现,但如果不依赖于另一个机箱(如itertools(中的结构,它就无法为其实现。类似地,itertools不能在不依赖rayon的情况下为其类型实现rayon::ParallelIterator

相反,您可以使用Rayon的API:自己复制Itertools::cartesian_product的功能

use rayon::iter::{ParallelIterator, IntoParallelIterator};
fn main() {
(0..15).into_par_iter()
.flat_map(|i| (0..8).into_par_iter().map(move |j| (i, j)))
.for_each(|x| println!("{:?}", x));
}

或者,您可以从一个长度为(15*8(的迭代器开始,然后使用除法和余数将其分解为元组:

use rayon::iter::{ParallelIterator, IntoParallelIterator};
fn main() {
let it = (0 .. 15 * 8).into_par_iter().map(|x| (x / 8, x % 8));
it.for_each(|x| println!("{:?}", x));
}

相关内容

  • 没有找到相关文章

最新更新