簡體   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