假设我们有一个i8要转换为i16 无符号扩展的类型。
我们不能进行简单的as强制转换,因为这将导致扩展。
println!("{:b}", -128i8); // 10000000 <- we want this zero-extended in an i16.
println!("{:b}", -128i8 as i16); // 1111111110000000 sign extended :(
Run Code Online (Sandbox Code Playgroud)
我们无法转换,因为类型的大小不同:
println!("{:b}", unsafe {mem::transmute::<_, i16>(128i8)});
// ^ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types :(
Run Code Online (Sandbox Code Playgroud)
我想出的最好的方法是以下复杂的铸造链:
println!("{:b}", -128i8 as u8 as u16 as i16); // 10000000 :), but :( because convoluted.
Run Code Online (Sandbox Code Playgroud)
中间转换 tou8意味着转换到 au16将零扩展而不是符号扩展,然后从u16to转换i16就可以了,因为类型大小相同并且不需要扩展。
但一定有更好的办法吗?有没有?
请记住,对于这种情况(打印数字的位),您可以只进行无符号转换。
然而,一般来说,Rust 并不喜欢进行隐式转换,但你总是可以写
let n : i8 = -128;
let m : i32 = n as u8 as i32;
Run Code Online (Sandbox Code Playgroud)
一般来说,你几乎找不到比这更好的了,因为双重转换在更改指针类型等领域很常见。当您正在执行的操作可以安全地完成且没有任何缺点(除了可能有轻微的代码味道)时,还请考虑不要使用 unsafe。
| 归档时间: |
|
| 查看次数: |
3205 次 |
| 最近记录: |