![](/img/trans.png)
[英]How to convert unsigned integer to signed integer without OverflowException
[英]Rust: How to cast from a signed integer type to a larger signed integer type *without* sign extension
假设我们有一个i8
,我们想在没有符号扩展的情况下将其转换为i16
。
我们不能做一个简单as
cast,因为这会扩展。
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
很好,因为类型的大小相同并且不需要扩展。
但一定有更好的方法吗? 在那儿?
请记住,对于这种情况(打印数字的位),您可以只进行无符号转换。
但是一般 Rust 并不喜欢进行隐式转换,但你总是可以写
let n : i8 = -128;
let m : i32 = n as u8 as i32;
一般来说,你几乎没有比这更好的了,因为双重转换在更改指针类型等领域很常见。 如果您正在执行的操作可以安全地完成而没有缺点(除了可能有轻微的代码气味),也请考虑不要使用 unsafe 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.