Rust のキャスト:明示的な型変換

RustRustBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Rust のキャストについて学び、as キーワードを使って明示的な型変換を行う方法を学びます。

注: 実験でファイル名が指定されていない場合は、好きなファイル名を使うことができます。たとえば、main.rs を使って、rustc main.rs &&./main でコンパイルして実行することができます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/AdvancedTopicsGroup -.-> rust/unsafe_rust("Unsafe Rust") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/integer_types -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/floating_types -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/type_casting -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/function_syntax -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/expressions_statements -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/lifetime_specifiers -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/unsafe_rust -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} rust/operator_overloading -.-> lab-99295{{"Rust のキャスト:明示的な型変換"}} end

キャスト

Rust では、基本型間で暗黙的な型変換(コーション)は行われません。ただし、明示的な型変換(キャスト)は as キーワードを使って行うことができます。

整数型間の変換の規則は、C の未定義動作の場合を除き、一般的に C の規則に従います。Rust では、整数型間のすべてのキャストの動作が明確に定義されています。

// オーバーフローするキャストからのすべての警告を抑制します。
#![allow(overflowing_literals)]

fn main() {
    let decimal = 65.4321_f32;

    // エラー!暗黙的な変換はありません
    let integer: u8 = decimal;
    // FIXME ^ この行をコメントアウトしてください

    // 明示的な変換
    let integer = decimal as u8;
    let character = integer as char;

    // エラー!変換規則には制限があります。
    // 浮動小数点数は直接 char に変換できません。
    let character = decimal as char;
    // FIXME ^ この行をコメントアウトしてください

    println!("Casting: {} -> {} -> {}", decimal, integer, character);

    // 任意の値を符号なし型 T にキャストする場合、
    // T::MAX + 1 が加算または減算されて、値が新しい型に収まるまで繰り返されます

    // 1000 は既に u16 に収まります
    println!("1000 as a u16 is: {}", 1000 as u16);

    // 1000 - 256 - 256 - 256 = 232
    // 内部的には、最初の 8 ビットの最下位ビット (LSB) が保持され、
    // それ以外の上位ビット (MSB) は切り捨てられます。
    println!("1000 as a u8 is : {}", 1000 as u8);
    // -1 + 256 = 255
    println!("  -1 as a u8 is : {}", (-1i8) as u8);

    // 正数の場合、これは剰余と同じです
    println!("1000 mod 256 is : {}", 1000 % 256);

    // 符号付き型にキャストする場合、(ビット単位の) 結果は、
    // まず対応する符号なし型にキャストする場合と同じです。その値の最上位ビットが 1 の場合、その値は負です。

    // もちろん、既に収まっている場合は除きます。
    println!(" 128 as a i16 is: {}", 128 as i16);

    // 境界ケースでは、8 ビットの 2 補数表現での 128 の値は -128 です
    println!(" 128 as a i8 is : {}", 128 as i8);

    // 上記の例を繰り返します
    // 1000 as u8 -> 232
    println!("1000 as a u8 is : {}", 1000 as u8);
    // 8 ビットの 2 補数表現での 232 の値は -24 です
    println!(" 232 as a i8 is : {}", 232 as i8);

    // Rust 1.45 以降、`as` キーワードは浮動小数点数から整数へのキャスト時に *飽和キャスト* を行います。
    // 浮動小数点数の値が上限を超えるか下限未満の場合、返される値は超えた境界に等しくなります。

    // 300.0 as u8 は 255 です
    println!(" 300.0 as u8 is : {}", 300.0_f32 as u8);
    // -100.0 as u8 は 0 です
    println!("-100.0 as u8 is : {}", -100.0_f32 as u8);
    // nan as u8 は 0 です
    println!("   nan as u8 is : {}", f32::NAN as u8);

    // この動作には小さな実行時コストがかかり、unsafe メソッドを使うことで回避できますが、
    // 結果はオーバーフローして **健全でない値** を返す場合があります。これらのメソッドは適切に使ってください:
    unsafe {
        // 300.0 as u8 は 44 です
        println!(" 300.0 as u8 is : {}", 300.0_f32.to_int_unchecked::<u8>());
        // -100.0 as u8 は 156 です
        println!("-100.0 as u8 is : {}", (-100.0_f32).to_int_unchecked::<u8>());
        // nan as u8 は 0 です
        println!("   nan as u8 is : {}", f32::NAN.to_int_unchecked::<u8>());
    }
}

まとめ

おめでとうございます!キャストの実験を完了しました。LabEx でさらに多くの実験を行って、スキルを向上させましょう。