3

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>`
1
  • 1
    Why do you bother to convert it? can't vec<u8> satisfy your use case? And it's mostly not recommanded because [u8] requires an explicit static size during the compile time. Commented Aug 7, 2022 at 15:53

3 Answers 3

9

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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"
    )
}

Comments

2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.