首页 > 解决方案 > 如何链接任意数量的迭代?

问题描述

我了解一些涉及迭代和数组的问题,但显然还不够。我想获取任意数量的可迭代对象(向量、数组、切片、任何实现IntoIterator)并提供预期的最终大小,并获得一个包含链接值的数组(即固定大小)。澄清一下,这主要是为了便于重构和函数调用,所以我希望这个实用程序拥有传递的迭代器的所有权并将它们的所有内容移动到它的输出中,例如:

let a1: u8 = [1, 2, 3];
let a2: u8 = [4, 5, 6];
let joined = join::<u8, 6>([a1, a2, ...]); // [u8; 6]

我尝试用 实现一些东西chain,但无法解决。我知道我可以做到这一点unsafe,但如果可能的话,我宁愿避免这样做。有没有办法做我想做的事?

我最好的(非工作)尝试:

fn join<T, C: IntoIterator<Item = T>, const N: usize>(iterables: Vec<C>) -> [T; N] {
  let mut a = vec![].iter().chain(vec![]);
  for iterable in iterables {
    a = a.chain(iterable.into_iter());
  }
  a.collect().try_into().unwrap()
}

标签: rust

解决方案


感谢@SvenMarnach 的简化,这个问题就这样被巧妙地解决了:

use std::convert::TryInto;

fn join<T: Clone, const N: usize>(iterables: Vec<&[T]>) -> [T; N] {
  let slice = iterables.concat();
  let length = slice.len();
  slice.try_into()
    .unwrap_or_else(|_| panic!("joined has length {}, expected {}", length, N))
}

像这样使用:

fn main() {
  let params1 = [1, 2, 3];
  let params2 = [4, 5];
  print!("sum: {}", sum_six_numbers(join(vec![&params1, &params2])));
}

fn sum_six_numbers(ns: [u8; 5]) -> u8 {
  ns.iter().sum()
}

推荐阅读