首页 > 解决方案 > 有什么方法可以使闭包采用解构数组?

问题描述

我正在做这个代码高尔夫挑战,并想出了这个问题的解决方案:

fn main() {
    let f = |s:&[u8]|s.chunks(2).all(|n|n[0]==n[1]);
    println!("{}", f(b"TThhiiss  iiss  ddoouubbllee  ssppeeaakk!!"));
}

该解决方案有效,但我认为n[0]==n[1]看起来不太优雅并尝试了类似的方法:

fn main() {
    let f = |s:&[u8]|s.chunks(2).all(|[a,b]|a==b);
    println!("{}", f(b"TThhiiss  iiss  ddoouubbllee  ssppeeaakk!!"));
}

但这失败并出现错误:

error[E0005]: refutable pattern in function argument: `&[]` not covered
 --> src/main.rs:2:39
  |
2 |     let f = |s:&[u8]|s.chunks(2).all(|[a,b]|a==b);
  |                                       ^^^^^ pattern `&[]` not covered

有没有办法通过改变闭包参数来完成上述工作(其他一切都应该保持原样):

fn main() {
    let f = |s:&[u8]|s.chunks(2).all(|/* anything here */|a==b);
    println!("{}", f(b"TThhiiss  iiss  ddoouubbllee  ssppeeaakk!!"));
}

标签: parametersrustpattern-matchingclosures

解决方案


不。

函数参数是模式,并且这些模式必须始终是无可辩驳的。


使用itertools,您可以这样做:

use itertools::Itertools;

fn main() {
    let f = |s:&[u8]|s.iter().tuples().all(|(a,b)|a==b);
    println!("{}", f(b"TThhiiss  iiss  ddoouubbllee  ssppeeaakk!!"));
}

这可以工作,因为tuples它会推断它恰好需要 2 个元素。如果有奇数个元素,最后一个将被忽略。


推荐阅读