yegor256
yegor256

Reputation: 105043

How to covert a vector of bytes to a byte array in Rust?

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

Answers (3)

jfMR
jfMR

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

tieway59
tieway59

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

at54321
at54321

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

Related Questions