&[u8] 不能被 RangeFull 索引? [英] &[u8] cannot be indexed by 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();
}
这篇关于&[u8] 不能被 RangeFull 索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!