How to convert &[i8] to &[u8]?


#1

I tried to use
let u8slice : &[u8] = i8slice as &[u8];
But it complains

an as expression can only be used to convert between primitive types. Consider using the From trait

I don’t know how to “use the From trait” to fix this problem.


#2

OK, I use the following code to fix it.

let u8slice : &[u8] = unsafe{ slice::from_raw_parts(i8slice.as_ptr() as *const u8, i8slice.len()) };


#3

std::mem::transmute is another option here.


#4

The std:mem::transmute docs recommend something like this instead of transmute:

let u8slice = unsafe { &*(i8slice as *[i8] as *[u8]) };

#5

Yeah you can do:

let u8slice = unsafe { &*(i8slice as *const _  as *const [u8]) };

Too noisy for my liking :slight_smile:


#6

I think Rust+std should offer a way to perform this conversion without the need of unsafe code.


#7

There are a bunch of examples of conversions that are safe with as but stop working behind references or aggregates or similar. For example, &i8 <-> &u8 and [i8; 2] <-> [u8;2] and Vec<i8> <-> Vec<u8>.

There’s some conversations going on around this area on IRLO:


#8
let mut v: Vec<u8> = vec![0, 0, 0, 4, 240, 159, 146, 150];
let mut v_slice = &mut v[2..5];
let mut v_slice = unsafe{ &*( v_slice as *mut [u8] as *mut [i8] ) };
println!("{:?}", v_slice);