Предположим, у нас есть i8
, которое мы хотим преобразовать в i16
без расширения знака .
Мы не можем выполнить простое преобразование as
, так как это будет означать расширение.
println!("{:b}", -128i8); // 10000000 <- we want this zero-extended in an i16.
println!("{:b}", -128i8 as i16); // 1111111110000000 sign extended :(
Мы не можем преобразовать, потому что типы имеют разный размер:
println!("{:b}", unsafe {mem::transmute::<_, i16>(128i8)});
// ^ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types :(
Лучшее, что я придумал, - это следующая запутанная цепочка литья:
println!("{:b}", -128i8 as u8 as u16 as i16); // 10000000 :), but :( because convoluted.
Промежуточное приведение к u8
означает, что приведение к u16
будет расширяться нулем вместо расширения знака, тогда приведение от u16
к i16
нормально, поскольку типы одинакового размера, и расширение не требуется.
Но должен ли быть лучший способ? Есть?