问题
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();
}
I get the error
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]`
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?
回答1:
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.
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.)
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();
}
Playground example
来源:https://stackoverflow.com/questions/64088594/u8-cannot-be-indexed-by-rangefull