&[u8] 不能被 RangeFull 索引? [英] &[u8] cannot be indexed by RangeFull?

查看:37
本文介绍了&[u8] 不能被 RangeFull 索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个结构体,该结构体可以包含可切片到 [u8] 的任何内容.

I am trying to create a struct which can contain anything that is sliceable to [u8].

use std::ops::{Index, RangeFull};

struct Wrapper<DataT>
where
    DataT: ?Sized + Index<RangeFull, Output = [u8]>, 
{
    data: DataT,
}

impl<DataT> Wrapper<DataT>
where
    DataT: ?Sized + Index<RangeFull, Output = [u8]>, 
{
    
    fn subwrapper(&self) -> Wrapper<Vec<u8>> {
        let mut buffer = Vec::<u8>::new();
        buffer.extend_from_slice(&self.data[..]);
        Wrapper {
            data: buffer,
        }
    }
}

fn main() {
    let data : [u8; 3] = [1, 2, 3];
    let w = Wrapper {data: &data[..]};
    let sub = w.subwrapper();
}

我收到错误

error[E0277]: the type `&[u8]` cannot be indexed by `std::ops::RangeFull`
  --> src/main.rs:24:13
   |
3  | / struct Wrapper<DataT>
4  | | where
5  | |     DataT: ?Sized + Index<RangeFull, Output = [u8]>, {
6  | |         data: DataT,
7  | |     }
   | |_____- required by `Wrapper`
...
24 |       let w = Wrapper {data: &data[..]};
   |               ^^^^^^^ `&[u8]` cannot be indexed by `std::ops::RangeFull`
   |
   = help: the trait `std::ops::Index<std::ops::RangeFull>` is not implemented for `&[u8]`

我关注了数组不能被 RangeFull 索引?,但它没有似乎不能解决问题.这是因为 &[u8] 是一个切片吗?当我尝试使用 SliceIndex 特性时,它似乎破坏了 Vec.有没有办法说这两种特质都可以接受?

I followed Array cannot be indexed by RangeFull?, but it didn't seem to solve the issue. Is this because &[u8] is a slice? When I try using the SliceIndex trait it seems to break for the Vec. Is there a way to say either trait is acceptable?

推荐答案

这里的问题是,虽然切片 [u8] 实现了 Index,但引用到切片 &[u8] 没有.它是您试图存储在 Wrapper 中的引用,因此 DataT 被推断为 &[u8],因此特征bound DataT: Index 不满足.

The problem here is that while a slice [u8] implements Index<RangeFull>, a reference to a slice &[u8] does not. And it is the reference that you're trying to store in Wrapper so DataT is inferred to be &[u8], thus the trait bound DataT: Index<FullRange> is not satisfied.

如果您的目标是涵盖任何可切片到 [u8] 的内容",那么您可能应该使用其他特征.像 AsRef<[u8]> 在这里可能会更好,因为它表示对这种类型的引用可以转换为对切片 [u8] 的引用",这可能是一个更sliceable to [u8]"的合适定义.(其他特征,如 Deref<Target = [u8]> 在这里也可能是合适的替代品.)

If your goal is to cover "anything that's sliceable to [u8]", you should likely use other traits, though. A trait like AsRef<[u8]> might be better here, as it indicates "a reference to this type can be converted into a reference of a slice [u8]", which might be a more suitable definition of "sliceable to [u8]". (Other traits like Deref<Target = [u8]> might also be suitable alterantives here.)

使用AsRef,你的代码会变成:

Using AsRef, your code would become:

struct Wrapper<DataT>
where
    DataT: AsRef<[u8]>, // <-- new trait bound
{
    data: DataT,
}

impl<DataT> Wrapper<DataT>
where
    DataT: AsRef<[u8]>, // <-- new trait bound
{
    fn subwrapper(&self) -> Wrapper<Vec<u8>> {
        let buffer = self.data.as_ref() // <-- use `.as_ref()` to get `&[u8]`
            .to_vec();                  // <-- more efficient way to get `Vec<u8>`
                                        //       from `&[u8]`
        Wrapper { data: buffer }
    }
}

fn main() {
    let data: [u8; 3] = [1, 2, 3];
    let w = Wrapper { data: &data }; // <-- no need to use `[..]` here, as
                                     //       `[u8; N]` implements `AsRef<[u8]>`
    let sub = w.subwrapper();
}

游乐场示例

这篇关于&amp;[u8] 不能被 RangeFull 索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆