[英]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)
}
使用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.