はじめに
今回は「Rust」の文法について解説します。「変数」に「データ型」がある点や「if文」「for文」などは、一般的なプログラミング言語「C++」などの文法とよく似ています。
Rustもオブジェクト指向も使えるプログラミング言語ですが、「クラス(class)」ではなく「構造体(struct)」でオブジェクト指向を実現します。Rustの関数の宣言に「関数名」「引数」「戻り値」がある点も一般のプログラミング言語とよく似ています。
Rustはデータ型やメモリの管理など実行時だけでなく、ビルド時にも非常に厳密にコーディングされなければ実行ファイルを作成できません。そのため、よく文法を理解して正しい処理のコードを書きましょう。
Think ITをご覧の方々なら何らかのプログラミング言語は使えるでしょうから、サンプルコードを見れば何となくRustと他のプログラミング言語との共通点から文法が分かると思います。
「変数」について
変数とは、プログラミング言語においてよく「値を入れたり中身の値を取り出す入れ物」と例えられますが、Rustにおいてもほぼ同じです(図1)。ただし、Rustにおいて変数にはメモリを割り当てておく「所有権」が存在します。所有権については次回で解説します。
図1:値を「変数」の入れ物に出し入れ
例えば、次のサンプルコードのように変数をコーディングします。
・変数の文字列を出し入れするサンプルコード
2 | let hello = "Hello, world!"; |
【サンプルコードの解説】
「let hello = "Hello, world!";」で「hello」変数に文字列"Hello, world!"を代入して、「let」で宣言します。
「println!("{}",hello);」で「hello」変数の値を取得して、ターミナルに文字列"Hello, world!"を表示します。
「データ型」について
プログラミング言語によっては、データ型が整数と実数、文字列にしか分かれていないこともありますが、Rustでは下表のように厳密に数値のビット数ごとにデータ型が分かれています。
「u」は正の整数を、「i」は整数を、「f」は実数を表し、その後ろに続く数値がビット数を表しています。「bool」型は真か偽の2択です。「char」型の文字や「str」型の文字列はユニコードで扱います。
表:「データ型」の種類
データ型 |
説明 |
bool型 |
trueとfalseの真偽値 |
u8型 |
8bitの0~255の符号なし整数 |
u16型 |
16bitの0~65535の符号なし整数 |
u32型 |
32bitの0~4294967295の符号なし整数 |
u64型 |
64bitの0~18446744073709551615の符号なし整数 |
usize型 |
32bitと64bitの0~18446744073709551615の符号なし整数 |
i8型 |
8bitの-128~127の整数 |
i16型 |
16bitの-32768~32767の整数 |
i32型 |
32bitの-2147483648~2147483647の整数 |
i64型 |
64bitの-9223372036854775808~9223372036854775807の整数 |
isize型 |
32bitと64bitの-9223372036854775808~9223372036854775807の整数 |
f32型 |
32bitの-3.4028235e38~3.4028235e38の実数 |
f64型 |
64bitの-1.7976931348623157e308~1.7976931348623157e308の実数 |
char型 |
1文字のユニコード文字 |
str型 |
ユニコード文字列 |
・数値の「変数」を出し入れするサンプルコード
2 | let variable1:u32 = 123456789; |
3 | println!("variable1 = {}",variable1); |
【サンプルコードの解説】
「let variable1:u32 = 123456789;」で「u32」型の数値「123456789」を「variable1」変数に代入して、「let」で宣言します。
「println!("variable1 = {}",variable1);」で「variable1」変数から数値を取得し「println!」マクロの「{}」に値を渡して、文字列"variable1 = 123456789"をターミナルに表示します。
・「可変」の「変数」を出し入れするサンプルコード
2 | let mut variable2:i32 = 987654321; |
4 | println!("variable2 = {}",variable2); |
【サンプルコードの解説】
「let mut variable2:i32 = 987654321;」で「variable2」変数を「let mut」で宣言します。「可変」を意味する「mut(mutable)」が付くのは後から値を変更できるようにするためです。
「variable2 = 54321;」は「mut」なので値を変更できます。ターミナルに"variable2 = 54321"を表示します。
こんな感じで、ビルドの際にはこと細かくコードが精査されます。
「配列」について
配列とは、複数の変数をまとめて保持する入れ物のようなものです(図2)。同じデータ型の変数がたくさんある場合に一度に処理するのに役立ちます。
配列は「[ ]」で囲って表します。値を入れることも取り出すこともできます。
図2:複数の値を「配列」の入れ物に出し入れ
・「配列」に値を出し入れするサンプルコード
2 | let array1:[i32;4] = [0,1,2,3]; |
3 | println!("array1[0] = {}",array1[0]); |
【サンプルコードの解説】
「let array1:[i32;4] = [0,1,2,3];」で「i32」型の変数が4個の「配列」に、0インデックスから順に「0」「1」「2」「3」の値を代入して「array1」配列を「let」で宣言します。
「println!("array1[0] = {}",array1[0]);」で「array1」配列の0インデックスの値を取得し、「println!」マクロの「{}」に値を渡してターミナルに"array1[0] = 0"を表示します。
・「配列」に「可変」の値を出し入れするサンプルコード
2 | let mut array2:[u32;3] = [4,5,6]; |
4 | println!("array2[1] = {}",array2[1]); |
【サンプルコードの解説】
「let mut array2:[u32;3] = [4,5,6];」で「u32」型の変数が3個の「配列」に、0インデックスから順に「4」「5」「6」の値を代入して「array2」配列を「let mut」で宣言します。「可変」を意味する「mut(mutable)」が付くのは後から値を変更できるようにするためです。
「array2[1] = 10;」で「array2」配列の1インデックスに10を代入します。ただし「array2」変数の宣言時に「mut」を付けた場合だけです。ターミナルには"array2[1] = 10"を表示します。
「タプル」について
タプルは配列と同様に、複数の変数をまとめて保持する入れ物のようなものです。配列と違い、異なるデータ型の値を一度に保持できます。タプルは「()」で囲って値を代入します。代入は宣言時にできます。値の取得は0インデックスは「配列名.0」、1インデックスは「配列名.1」のようにして取り出せます。
・値をタプルに出し入れするサンプルコード
2 | let tup1 = (1,"A","B"); |
3 | println!("tup1.0 = {}",tup1.0); |
【サンプルコードの解説】
タプルに0インデックスから順に「1」「A」「B」を代入して、「let」で「tup1」タプルを宣言します。
「tup1.0」で「tup1」タプルの0インデックスの「1」を取得してターミナルに"tup1.0 = 1"を表示します。
・「可変」の値を「タプル」に出し入れするサンプルコード
2 | let mut tup2 = ("X",2); |
4 | println!("tup2.1 = {}",tup2.1); |
【サンプルコードの解説】
タプルに0インデックスから順に「X」「2」を代入して、「let mut」で「tup2」タプルを宣言します。「可変」を意味する「mut(mutable)」が付くのは後から値を変更できるようにするためです。
「tup2.1 = 20;」で「tup2」タプルの1インデックスに20を代入します。ただし「tup2」タプルの宣言時に「mut」を付けた場合だけです。ターミナルに"tup2.1 = 20"を表示します。
「加減乗除」について
Rustの「加減乗除」も一般のプログラミング言語とほぼ同じです。プログラミングの計算はプリミティブなところまでさかのぼれば、加減乗除だけでも大体のことができます。
・「加減乗除」のサンプルコード
【サンプルコードの解説】
「可変(mut)」の「a」変数に2を代入して「let」で宣言します。加算は「+」、減算は「-」、乗算は「*」、除算は「/」、剰余(除算した余り)は「%」で計算します。