I want to flatten a vector containing &[u8]:
fn main() {
let x: &[u8] = &b"abc"[..];
let y: &[u8] = &b"def"[..];
let z: Vec<&[u8]> = vec![x, y];
println!("z: {:?}", z);
let z_flat: &[u8] = z.into_iter().flatten().collect();
println!("z_flat: {:?}", z_flat);
}
I get the compiler error:
error[E0277]: a value of type `&[u8]` cannot be built from an iterator over elements of type `&u8`
--> src/main.rs:9:49
|
9 | let z_flat: &[u8] = z.into_iter().flatten().collect();
| ^^^^^^^ value of type `&[u8]` cannot be built from `std::iter::Iterator<Item=&u8>`
|
= help: the trait `FromIterator<&u8>` is not implemented for `&[u8]`
I have also tried the following:
let z_flat: &[u8] = &z.into_iter().map(|x| x.to_vec()).flatten().collect();
Compile error:
error[E0277]: a value of type `[u8]` cannot be built from an iterator over elements of type `u8`
--> src/main.rs:9:70
|
9 | let z_flat: &[u8] = &z.into_iter().map(|x| x.to_vec()).flatten().collect();
| ^^^^^^^ value of type `[u8]` cannot be built from `std::iter::Iterator<Item=u8>`
|
= help: the trait `FromIterator<u8>` is not implemented for `[u8]`
The following does work (playground):
let z_flat: &[u8] = &z.concat();
I am not able to use concat in my real-world application because I am using another struct when retrieving the nested bytes (x and y) and this struct cannot implement Copy (only Clone) because it contains a Vec<u8> field. I have something similar to this (playground):
#[derive(Clone, Debug)]
struct Foo {
Bar: Vec<u8>,
}
impl Foo {
fn baz(&self) -> Vec<u8> {
self.Bar
}
}
fn main() {
let x = Foo { Bar: vec![8u8] };
let y = Foo { Bar: vec![18u8] };
let z: Vec<Foo> = vec![x, y];
println!("z: {:?}", z);
let z_flat = z
.into_iter()
.map(|x| &x.baz()[..])
.collect::<Vec<&[u8]>>()
.concat();
println!("z_flat: {:?}", z_flat);
}
Compile error:
error[E0507]: cannot move out of `self.Bar` which is behind a shared reference
--> src/main.rs:8:9
|
8 | self.Bar
| ^^^^^^^^ move occurs because `self.Bar` has type `Vec<u8>`, which does not implement the `Copy` trait
error[E0515]: cannot return value referencing temporary value
--> src/main.rs:22:18
|
22 | .map(|x| &x.baz()[..])
| ^-------^^^^
| ||
| |temporary value created here
| returns a value referencing data owned by the current function