我想展平包含 &[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);
}
我得到编译器错误:
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]`
我也试过以下方法:
let z_flat: &[u8] = &z.into_iter().map(|x| x.to_vec()).flatten().collect();
编译错误:
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]`
以下确实有效(playground):
let z_flat: &[u8] = &z.concat();
我无法使用 concat
在我的实际应用程序中,因为我在检索嵌套字节( x
和 y
)时使用了另一个结构,并且此结构无法实现 Copy
(仅 Clone
)因为它包含一个 Vec<u8>
field 。我有类似的东西 ( 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);
}
编译错误:
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
最佳答案
不,这是不可能的。根据定义,切片是一个连续的内存区域。你没有那个开始,所以你不能创建一个切片。
您的解决方法是将所有内容复制到一个连续的内存块中,然后您可以获取其中的一部分。我会这样写:
let z: Vec<&[u8]> = vec![b"abc", b"def"];
let z_alloc: Vec<u8> = z.iter().flat_map(|&x| x).copied().collect();
let z_flat: &[u8] = &z_alloc;
println!("z_flat: {:?}", z_flat);
对于更大的例子:
// fn baz(self) -> Vec<u8>
let z_flat: Vec<u8> = z.into_iter().flat_map(Foo::baz).collect();
// fn baz(&self) -> &[u8]
let z_flat: Vec<u8> = z.iter().flat_map(Foo::baz).copied().collect();
另见:
关于rust - 是否可以在不复制数据的情况下将 Vec<&[u8]> 展平为 &[u8] ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68625669/