跳轉到內容

Rust 新手程式設計師/數字轉換

100% developed
來自華夏公益教科書

數字轉換

[編輯 | 編輯原始碼]

如果我們有一個型別為(例如 u8)的數字,並且我們想將其轉換為另一種型別(例如 i32)的數字,我們該如何做呢?數字型別轉換的一個重要原則是增加位數總是安全的。然而,反過來可能存在風險,因為我們可能會丟失資訊。因此,如果我們正在進行一個“安全”的向上轉換,那麼有一些簡單的方法可以做到這一點。

 fn main() {
     let number1: u8 = 10;
     let number2 = i32::from(number1);
     let number3: i32 = number1.into();
 }

最後,所有這些都將是 10。注意,對於第三個,我們指定了 number3 的型別為 i32。如果我們沒有這樣做,它將無法編譯,因為編譯器必須知道變數的型別。如果我們稍後在需要 i32 的地方使用它,那麼編譯器可以推斷出它是一個 i32。這稱為型別推斷,它非常有助於減少我們編寫的冗餘程式碼量。

如果我們想反過來,從較大的型別轉換為較小的型別,最簡單的方法是使用關鍵字“as”進行強制轉換。這存在風險,因為如果數字是較小型別無法儲存的數字,那麼您將得到奇怪的行為。例如

 fn main() {
     let number1 = -10i32;
     let number2 = number1 as u8;
     println!("{}", number2);
 }

這將打印出 246。注意,我們在 -10 的末尾使用 i32 來放置型別。這只是另一種方法;您可能喜歡或不喜歡它,但這是一種值得了解的選項。打印出 246 的原因是 u8 只能儲存從 0 到 255 的數字。從 256 開始的第 10 個數字是 246。然而,您極少會想要依賴這種行為,因此我們改為這樣做

 fn main() {
     let number1 = 10i32;
     let number2: u8 = number1.try_into().unwrap();
     println!("{}", number2);
 }

現在我們必須在 number2 上使用顯式型別來表明我們想將其轉換為 u8。try_into() 函式嘗試將其轉換為一個數字並返回一個稱為“Result”的型別,該型別指示轉換是否成功。unwrap() 意味著我們假設轉換成功。如果轉換不成功,即另一個數字不能用新的數字型別表示,那麼程式將崩潰,這在 Rust 中稱為恐慌。由於數字無法正確轉換而導致崩潰可能看起來很奇怪,但這是一個重要的概念。如果出了問題,我們想做什麼?我們有兩個選擇:中止並停止執行,或者繼續執行並嘗試使用我們現有的東西。然而,小的錯誤會導致看不見的後果。程式通常依賴於我們預期的值或數字。如果我們使用“as”進行轉換,我們很容易得到奇怪的意外結果,這些結果會導致程式中更深層次的錯誤,這些錯誤非常難以追蹤。相反,我們通常希望直接崩潰並能夠確定存在錯誤以及錯誤發生的位置,從而允許我們修復錯誤。只有在極少數情況下,我們才希望在數字不匹配時依賴“as”的奇怪行為。

回到上一章的問題,我們想從 get_median() 函式返回一個浮點數。我們可以從函式中返回一個 f64,因為 f64 比 i32 大,所以我們可以使用安全轉換方法。

 fn get_median(input: Vec<i32>) -> f64 {
     let mut array = input;
     //sort array
     for index1 in 0..array.len() {
         for index2 in index1..array.len() {
             if array[index2] > array[index1] {
                 array.swap(index1, index2);
             }
         }
     }
     //return median
     if array.len() % 2 == 0 {
         //even
         let middle_value1 = array[array.len() / 2 - 1].into();
         let middle_value2 = array[array.len() / 2].into();
         let median = (middle_value1 + middle_value2) / 2.0;
         return median;
     } else {
         //odd
         let median = array[array.len() / 2].into();
         return median;
     }
 }

注意,因為我們從函式返回一個 f64,所以編譯器可以計算出當我們使用 .into() 時,我們想要一個 f64,因此我們不必寫出型別。現在這個函式按預期工作,返回正確的中值。

下一個: 元組和結構體

華夏公益教科書