繁体   English   中英

Rust:如何从签名的 integer 类型转换为更大的签名 integer 类型 *无*符号扩展

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM