簡體   English   中英

如何轉換 [u8; 的迭代器; 4]進入u8的迭代器?

[英]How to convert an iterator of [u8; 4] into an iterator of u8?

我有需要擴展為更多字節的u8數據, [u8; 4] [u8; 4]通過 function 並作為迭代器整體傳遞到消耗它的第二個 function 中。

以下編譯但不起作用,因為它多次調用消費 function :

fn expand(b: u8) -> [u8; 4] {
    const T: [u8; 4] = [0x12, 0x34, 0x56, 0x78];
    [
        T[((b >> 6) & 0b11) as usize],
        T[((b >> 4) & 0b11) as usize],
        T[((b >> 2) & 0b11) as usize],
        T[((b >> 0) & 0b11) as usize],
    ]
}

fn process2(data: impl Iterator<Item = [u8; 4]>) {
    for x in data {
        process(x.iter().cloned());
    }
}

fn process(data: impl Iterator<Item = u8>) { 
    for x in data {
        println!("{:02x}", x);
    }
}

fn main() {
    let xs = [1, 2, 3, 4];
    process2(xs.iter().map(|x| expand(*x)));
}

操場

flat_map似乎是答案,但我遇到了終身問題:

    process(xs.iter().map(|x| expand(*x)).flat_map(|x| x.iter().cloned()));

給我:

error[E0515]: cannot return value referencing function parameter `x`
  --> src/main.rs:27:56
   |
27 |     process(xs.iter().map(|x| expand(*x)).flat_map(|x| x.iter().cloned()));
   |                                                        -^^^^^^^^^^^^^^^^
   |                                                        |
   |                                                        returns a value referencing data owned by the current function
   |                                                        `x` is borrowed here

如何轉換Iterator<Item=[u8; 4]> Iterator<Item=[u8; 4]>進入Iterator<Item=u8>

您不能只使用 Rust 1.49 穩定標准庫。

每晚

使用array::IntoIter

// 1.52.0-nightly (2021-02-09 097bc6a84f2280a889b9)
use std::array;

fn example() -> impl Iterator<Item = u8> {
    let data: [u8; 4] = [1, 2, 3, 4];
    array::IntoIter::new(data)
}

穩定Rust

使用arrayvec

use arrayvec::ArrayVec; // 0.5.2

fn example() -> impl Iterator<Item = u8> {
    let data: [u8; 4] = [1, 2, 3, 4];
    ArrayVec::from(data).into_iter()
}

應用它

然后,您可以將Iterator::flat_map與任一解決方案一起使用:

use arrayvec::ArrayVec; // 0.5.2

fn example(data: [u8; 4]) -> impl Iterator<Item = u8> {
    ArrayVec::from(data).into_iter()
}

fn drive_it(i: impl Iterator<Item = [u8; 4]>) -> impl Iterator<Item = u8> {
    i.flat_map(example)
}

也可以看看:

我建議創建一個自定義迭代器:

struct NameMe {
    i: u8,
    v: u8,
}

impl NameMe {
    fn new(v: u8) -> Self {
        Self { i: 8, v }
    }
}

impl Iterator for NameMe {
    type Item = u8;

    fn next(&mut self) -> Option<Self::Item> {
        const T: [u8; 4] = [0x12, 0x34, 0x56, 0x78];

        if self.i != 0 {
            self.i -= 2;

            Some(T[((self.v >> self.i) & 0b11) as usize])
        } else {
            None
        }
    }
}

fn main() {
    let xs = [1, 2, 3, 4];

    let result: Vec<_> = xs.iter().copied().flat_map(NameMe::new).collect();

    let expect = [
        0x12, 0x12, 0x12, 0x34, 0x12, 0x12, 0x12, 0x56, 0x12, 0x12, 0x12, 0x78, 0x12, 0x12, 0x34,
        0x12,
    ];

    assert_eq!(result, expect);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM