首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以将Vec<&[u8]>压缩为&[u8]而不复制数据吗?

可以将Vec<&[u8]>压缩为&[u8]而不复制数据吗?
EN

Stack Overflow用户
提问于 2021-08-02 17:21:14
回答 1查看 514关注 0票数 2

我想把包含&[u8]的向量压平

代码语言:javascript
复制
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);
}

我得到编译器错误:

代码语言:javascript
复制
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]`

我还尝试了以下几点:

代码语言:javascript
复制
let z_flat: &[u8] = &z.into_iter().map(|x| x.to_vec()).flatten().collect();

编译错误:

代码语言:javascript
复制
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]`

以下执行工作(游乐场):

代码语言:javascript
复制
let z_flat: &[u8] = &z.concat();

我无法在我的实际应用程序中使用concat,因为在检索嵌套字节(xy)时,我使用的是另一个结构,而且这个结构不能实现Copy (只有Clone),因为它包含一个Vec<u8>字段。我有一些类似于此(游乐场)的内容:

代码语言:javascript
复制
#[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);
}

编译错误:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-02 17:26:28

不这是不可能的。根据定义,片是内存的一个连续区域。你一开始就没有这样的东西,所以你不能创建一个切片。

您的解决方案将所有内容复制到一个连续的内存块中,然后您可以从中获得一个片段。我会写这样的东西:

代码语言:javascript
复制
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);

对于更大的例子:

代码语言:javascript
复制
// fn baz(self) -> Vec<u8>
let z_flat: Vec<u8> = z.into_iter().flat_map(Foo::baz).collect();
代码语言:javascript
复制
// fn baz(&self) -> &[u8]
let z_flat: Vec<u8> = z.iter().flat_map(Foo::baz).copied().collect();

另请参阅:

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68625669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档