はじめに
この実験では、Rust のキャストについて学び、as
キーワードを使って明示的な型変換を行う方法を学びます。
注: 実験でファイル名が指定されていない場合は、好きなファイル名を使うことができます。たとえば、
main.rs
を使って、rustc main.rs &&./main
でコンパイルして実行することができます。
This tutorial is from open-source community. Access the source code
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
この実験では、Rust のキャストについて学び、as
キーワードを使って明示的な型変換を行う方法を学びます。
注: 実験でファイル名が指定されていない場合は、好きなファイル名を使うことができます。たとえば、
main.rs
を使って、rustc main.rs &&./main
でコンパイルして実行することができます。
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 でさらに多くの実験を行って、スキルを向上させましょう。