首页 > 解决方案 > 为什么我不能使用切片模式来过滤 Window 迭代器?

问题描述

我有一个数字向量,并使用该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

我不知道那个错误意味着什么:例如,列表不能少于两个元素。也许闭包参数是错误的?我试图改变它,但这并没有改变任何东西。a并且在我的 IDE 中也b被正确检测到。u64这里发生了什么?

标签: rustclosures

解决方案


你,程序员,知道每个迭代值的长度都是 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
}

也可以看看:

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

也可以看看:

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

也可以看看:


推荐阅读