Reputation: 105043
I'm trying to do this, but doesn't work:
fn foo() {
let v = b"Hello".to_vec();
let a = v.as_bytes();
}
I'm getting:
error[E0599]: no method named `as_bytes` found for struct `Vec<u8>` in the current scope
--> foo
|
26 | let a = v.as_bytes();
| ^^^^^^^^ method not found in `Vec<u8>`
Upvotes: 3
Views: 19302
Reputation: 24738
In Rust, an array has its length encoded in its type – e.g., [u8; 5]
– it is a compile-time property, whereas a Vec
's length is a run-time property. Every byte array, [u8; N]
, implements TryFrom<Vec<u8>>
, so Vec<u8>
implements TryInto<[u8; N]>
as a result. Therefore, you can use try_into()
on a Vec<u8>
to convert it into a byte array:
let a: [u8; 5] = v.try_into().unwrap();
Note that TryInto::try_into()
returns a Result
for the reason explained above: the mismatch of the nature of the length property of a Vec
and an array – run-time and compile-time, respectively.
Why not convert the Vec<u8>
into a byte slice instead?
Keep in mind that you can easily create a byte slice (i.e., &[u8]
) from a Vec<T>
. A Vec<u8>
deref coerces into [u8]
as it implements Deref<Target=[u8]>
:
let v = b"Hello".to_vec();
let a: &[u8] = &v;
You can also call as_slice()
on a Vec<u8>
:
let a = v.as_slice();
This may be what you want because you are probably using a Vec
to be able to change the length at run time.
Upvotes: 8
Reputation: 301
If you don't wish to write the [u8; N]
type, you can choose not '.to_vec()' in the beginning and use *b"string"
to obtain the byte array directly without type annotation.
struct Pack {
data: Box<[u8]>,
}
fn foo() {
let mut p = Pack {
data: Box::new(*b"Hello!"),
};
p.data = Box::new(*b"Bye!");
}
#[test]
fn test() {
let v = *b"Hello!";
let boxed_v = Box::new(*b"Hello!");
assert_eq!(
format!("{} {} {} {} {}", v[0], v[1], v[2], v[3], v[4]),
"72 101 108 108 111"
);
assert_eq!(
format!(
"{} {} {} {} {}",
boxed_v[0], boxed_v[1], boxed_v[2], boxed_v[3], boxed_v[4]
),
"72 101 108 108 111"
)
}
Upvotes: 3
Reputation: 11708
Here is one way to covert a vector of bytes to a byte array:
use std::convert::TryInto;
fn main() {
let v: Vec<u8> = vec![44u8, 99u8];
println!("{v:?}");
let a: [u8; 2] = v.try_into().unwrap();
println!("{a:?}");
}
The size of the array needs to be known at compile time though.
Upvotes: 2