为什么我不能使用切片模式来过滤窗口迭代器?



我有一个数字向量,并使用windows(2)方法创建一个迭代器,为我提供相邻的对。例如,向量[1, 2, 3]转换为[1, 2], [2, 3]。我想使用find方法查找满足特定条件的切片:

fn step(g: u64) -> Option<(u64, u64)> {
let prime_list: Vec<u64> = vec![2, 3, 5, 7]; //For example
if prime_list.len() < 2 {
return None;
}
let res = prime_list.windows(2).find(|&&[a, b]| b - a == g)?;
//...
None
}

我收到一个错误:

error[E0005]: refutable pattern in function argument: `&&[]` not covered
--> src/lib.rs:6:43
|
6 |     let res = prime_list.windows(2).find(|&&[a, b]| b - a == g)?;
|                                           ^^^^^^^^ pattern `&&[]` not covered

我不知道这个错误是什么意思:例如,列表不能少于两个元素。也许闭包参数是错误的?我试图改变它,但这并没有改变任何东西。 在我的 IDE 中,ab也被正确检测为u64。这是怎么回事?

程序员知道每个迭代值的长度为 2,但你怎么知道呢?您只能从函数的散文文档中看出:

返回长度大小的所有连续窗口的迭代器。窗口重叠。如果切片短于大小,则迭代器不返回任何值。

编译器在任何地方都不知道这些信息。Windows的实现仅声明迭代的值将是一个切片:

impl<'a, T> Iterator for Windows<'a, T> {
type Item = &'a [T];
}

我会将切片转换为数组引用,丢弃任何长度错误的切片(您知道这不可能发生(:

use std::convert::TryFrom;
fn step(g: u64) -> Option<(u64, u64)> {
let prime_list: Vec<u64> = vec![2, 3, 5, 7]; // For example
if prime_list.len() < 2 {
return None;
}
let res = prime_list
.windows(2)
.flat_map(<&[u64; 2]>::try_from)
.find(|&&[a, b]| b - a == g)?;
//...
None
}

另请参阅:

  • 如何将切片转换为数组引用?
  • 如何在 &[u8] 切片中找到子序列?
  • 当没有类型参数或属性时,如何暗示值的类型?

或者,您可以使用整数迭代器并将其分块。

另请参阅:

  • 是否有等效于切片::块/窗口,供迭代器循环对、三元组等?

在将来的某个时候,const 泛型可能会稳定下来,并允许将数组长度烘焙到函数调用和返回类型中。

另请参阅:

  • 是否可以使用泛型的类型参数控制数组的大小?

最新更新