Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

型別轉換 as

本集目標

學會用 as 做數字型別轉換,以及更安全的替代方案。

概念說明

基本用法

第 1 章學過 Rust 不會自動轉型。需要轉換時用 as

fn main() {
    let x: i32 = 42;
    let y: f64 = x as f64;

    let a: f64 = 3.99;
    let b: i32 = a as i32; // 3,截斷小數,不是四捨五入
}

整數之間

小轉大——值不會變:

fn main() {
    let x: u8 = 200;
    let y: u32 = x as u32; // 200
}

大轉小——靜默截斷,不會報錯:

fn main() {
    let x: u32 = 300;
    let y: u8 = x as u8; // 44!300 = 256 + 44,只留最低的 8 個位元
}

有號無號之間也可能出意外:

fn main() {
    let x: i32 = -1;
    let y: u32 = x as u32; // 4294967295
}

From / Into:更安全的選擇

第 5 章學過 FromInto。它們只在轉換保證不會失敗的時候才存在:

fn main() {
    let x: i32 = 42;
    let y: f64 = f64::from(x); // OK
    let z: i32 = i32::from(3.14_f64); // 編譯錯誤!不保證安全
}

TryFrom / TryInto

可能失敗的轉換用 TryFrom——回傳 Result

use std::convert::TryFrom;

fn main() {
    let x: u32 = 300;
    let result = u8::try_from(x); // Err
    let y: u32 = 42;
    let result = u8::try_from(y); // Ok(42)
}

什麼時候用哪個

  • 能用 From / Into 就用——編譯期保證安全
  • 可能失敗用 TryFrom / TryInto——回傳 Result
  • as 只在你確實知道自己在做什麼的時候用

範例程式碼

use std::convert::TryFrom;

fn main() {
    // as 基本轉換
    let x: i32 = 42;
    let y: f64 = x as f64;
    println!("i32 {} → f64 {}", x, y);

    let a: f64 = 3.99;
    let b: i32 = a as i32;
    println!("f64 {} → i32 {}(截斷,不是四捨五入)", a, b);

    // 危險的靜默截斷
    let big: u32 = 300;
    let small: u8 = big as u8;
    println!("u32 {} → u8 {}(靜默截斷!)", big, small);

    // From:安全
    let safe: f64 = f64::from(42_i32);
    println!("From:{}", safe);

    // TryFrom:可能失敗
    match u8::try_from(300_u32) {
        Ok(v) => println!("TryFrom 成功:{}", v),
        Err(e) => println!("TryFrom 失敗:{}", e),
    }

    match u8::try_from(42_u32) {
        Ok(v) => println!("TryFrom 成功:{}", v),
        Err(e) => println!("TryFrom 失敗:{}", e),
    }
}

重點整理

  • as 做數字型別轉換:浮點轉整數截斷小數,大整數轉小整數靜默截斷
  • From / Into:只存在於保證安全的轉換
  • TryFrom / TryInto:可能失敗的轉換,回傳 Result
  • 優先用 From,其次 TryFrom,最後才 as