この記事について
Rustの基本型についてまとめます。
Rustは他の言語のと違って明示的に宣言しなくても標準ライブラリ(std)が読み込まれます。
基本型は全てその標準ライブラリ内で宣言・定義されています。詳しいことはRustの標準ライブラリのリファレンスを参照してください。
基本型の分類
Rustの基本型はC/C++の基本型にPythonなどの比較的新しい言語の基本型をミックスしたものようなものになっています。大まかにそれらの型を分類すると次のようになっています。
- 整数型
- 浮動小数点型
- 関数型
- bool型
- ポインタ・参照型
- タプル型
- char型・固定長の文字列型
- 配列型
はじめは全ての型を一挙に紹介しようと思ったのですが、公式ドキュメントを見ると型のトレイト(メンバメソッドみたいなもの)がかなりの量があり驚きました。そこで、今回は整数型についてのみ紹介します。
整数型
Cや多くの言語と同様に整数型を持っています。大きな違いは型のサイズによって細かく分類されている点です。
let a:i8 = 8; // 8bit整数型
let b:i16 = 16; // 16ビット整数型
let c:i32 = 32; // 32ビット整数型
let d:i64 = 64; // 64ビット整数型
let e:i128 = 128; //128ビット整数型
もちろんunsigned型もあります。
let a:u8 = 8; // 8bit整数型
let b:u16 = 16; // 16ビット符号なし整数型
let c:u32 = 32; // 32ビット符号なし整数型
let d:u64 = 64; // 64ビット符号なし整数型
let e:u128 = 128; //128ビット符号なし整数型
ハードウェアによって扱いやすい・高速に演算できる整数のサイズは変わってきます。そういった違いを吸収するためにハードウェアにとって都合のいいサイズの整数型(isize・usize)が定義されています。usizeは、配列のインデックスに使われます。
let idx:usize = 2;
let idx_diff:isize = -32;
let my_array = [1,2,3,4];
println!("{}", my_array[idx]); // 配列のインデックスにusizeの変数をつかう。
整数型の演算
型情報の取得
それぞれの整数型は表現できる値の範囲をmin_value()、max_value()関数を用いて取得することができるます。
let max_val = i32::max_value();
let min_val = i8::min_value();
数学演算子
Rustは以下の数学演算子をそれぞれの型に対してサポートしています。
/* bit演算 */
let c = a & b; // AND演算
let c = a | b; // OR演算
let c = a >> b; // 右シフト
let c = a << b; // 左シフト
/* 加算乗除 */
let c = a + b; // 加算
let c = a - b; // 減産
let c = a * b; // 乗算
let c = a / b; //除算
/* 比較演算 */
let c = a == b;
let c = a <= b;
let c = a < b;
let c = a > b;
let c = a >= b;
bit演算
Rustは演算子で定義されたビット演算以外に次のような演算を行う関数を標準で提供しています。
n.count_ones(); // ビット表現したときに現れる1の数を求める
n.count_zeros(); // ビットで表現したときに現れる0の数を求める
n.leading_zeros(); // ビットで表現したときの頭の0の数を求める
n.trailing_zeros(); // ビットで表現したときの末尾の0の数を求める
n.swap_bytes(); // byte順序を逆にする
n.rotate_right(4); // ラップする右シフト
n.rotate_left(4); // ラップする左シフト
エンディアン変換
ネットワークプログラミングをするときに悩ましいエンディアン変換の関数を提供しています。
a.from_be(0x1213i32); // ビッグエンディアンから実行環境のエンディアンへ
a.from_le(0x19218); //リトルエンディアンから実行環境のエンディアンへ
let b = a.to_be(); // 実行環境からビッグエンディアンへ
let b = a.to_le(); // 実行環境からリトルエンディアンへ
安全な整数型演算
Rustが最も力を入れている要素の一つに安全性があります。通常の 数値演算に加えて安全性に配慮した数値演算関数を別に提供しています。
Optionで演算結果をラップする関数
オーバーフローなどで演算ができない場合に備えて、結果をOptionでラップして返します。
let result = a.checked_add();
let val = result.unwrap();
もちろん、加算以外にも演算子で定義されている演算は全てこの仲間の(checked_xxxx)があります。
飽和する関数
演算結果がオーバフローするときは、その型で取りうる値で飽和します。
let result = a.saturating_add(100000000000000000000000000000000000);
ラップする関数
演算結果が飽和するときは、その型の最小の値にラップします。
let result = a.wrapping_add(10000000000000000000000000000);
オーバーフローチェックつきラップする関数
演算結果を(整数型, bool)のタプルとして返します。オーバーフローが発生した場合はboolはtrueとなります。
let result = a.overflowing_add(100000000000000000000000000000);