5

How would I cast a byte array to a primitive type in Rust?

let barry = [0, 0];
let shorty: u16 = barry;

I have already tried let shorty: u16 = barry as u16; but that didn't work due to a "non scalar cast".

4 Answers 4

5

You can use bitwise operations. Note that this depends on endianess.

fn main() {
   let barry = [0, 0];
   let shorty: u16 = barry[0] | (barry[1] << 8);
   println!("{0}", shorty);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer, and yeah, I'm aware of the endianess. I am using the standard library to get it to the native format.
Also, it appears that for this to work, barry[0] and barry[1] need to be cast to u16. let shorty: u16 = barry[0] as u16 | (barry[1] as u16 << 8);
I tried the web runner (rust-lang.org). Yet, to be honest, I am seriously behind on Rust language evolution so I can't tell.
4

There is an unsafe way to do it with raw pointers too. The benefit being that it works for any type that only exists on the stack. It's completely safe as long as the byte array is correctly formatted, since no pointers are being kept around or modified. Just make sure that no mutable references also exists while this is going on, I would recommend wrapping it into a function that takes a reference to a byte array and a type parameter (with the Clone trait) so that the borrow checker can deal with that case.

let bytes = [0u8, 0u8];
let value = unsafe {
    let byte_ptr = bytes.as_ptr();
    let ptr = byte_ptr as *const u16; // This could be any type
    (*ptr).clone() // We clone it so that no 
                   // matter what type it is, it gets dereferenced. 
};

Comments

3

The byteorder crate is great for this. You can specify endianness, etc.

Comments

2

Depending on the endianness you want, you can use either of the methods from_be_bytes(), from_le_bytes() or from_ne_bytes() of the primitive types, since Rust 1.32.0.

E.g.:

let barry = [0, 0];
let shorty = u16::from_be_bytes(barry);

Playground

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.