Rustでは型キャスティング(type casting)はキーワード as を使って行われます。これはある型を別の型に明示的に変換します:
let x: i32 = 10; let y: u8 = x as u8;
RustはCやC++のように暗黙の変換(implicit cast)を行わないため、データ損失やオーバーフローに関する多くのエラーを防ぎます。
特徴:
潜在的な危険:
i32 から u8 へのキャストの際、値が範囲を超えると余分な上位ビットが単純に切り捨てられます。これは予期しない動作を引き起こす可能性があります。例:
let big: u16 = 300; let small: u8 = big as u8; // small == 44, 300 % 256 = 44
負の数
i8をasキーワードを用いてu8型にキャストした場合、何が起こりますか?
回答: 値はコンパイルエラーや実行時のパニックを引き起こしません。代わりに、値のビットは符号なし数として解釈されます:
let x: i8 = -1; let y: u8 = x as u8; // y == 255
物語
金融アプリケーションでは、送金額のデータは最初に i32 として保存されていました。開発者は範囲のチェックをせずに u32 に変換することにしたため、負の値の処理が不正確になり、合計が予期しない大きな正の数になり、ビジネスロジックの検証を通過してしまいました!
物語
マイクロコントローラー用のゲームでは、加速レベルの切り替えは2つのレベル値の差として計算されました。結果は負になる可能性がありました。結果を丸めるために as u8 キャストが使用され、オーバーフローが無視されました。その結果、負の値が大きな正の数に変わるため、速度が最大レベルで「フリーズ」してしまいました。
物語
ネットワークアプリケーションでは、データバッファのコピー時に長さがポインタ (usize) の差として計算され、その後 as を使用して u32 にキャストされました。大きなメモリ量(>4 GB)の場合、これにより値が切り捨てられ、大きなファイルの転送時にデータが剪断されるエラーが発生しました。