Rustの構文
Rustを動かせるようになったので、ここでひと息ついて、プログラムの各部分が実際に何を意味しているのかを見ていきましょう。いちばん小さな例を使って、ひとつずつ分解していきます。
fn main() { println!("こんにちは、世界!");}実行結果:
こんにちは、世界!main 関数
Section titled “main 関数”fn main() { // ここに書いたコードが実行される}Rustのプログラムはすべて、main という名前の関数から始まります。プログラムを実行すると、Rustは main を探して、その中のコードを実行します。
fnは関数(名前の付いたコードのかたまり)を定義するためのキーワードです。mainは関数の名前です。この名前は特別で、プログラムの入り口(エントリーポイント)になります。()には関数が受け取る入力が入ります(ここでは空です。mainは何も受け取りません)。{ }の波かっこが、関数に属するコード、つまり本体を囲みます。
文はセミコロンで終わる
Section titled “文はセミコロンで終わる”本体の中にある一つひとつの命令は、たいてい文(statement)です。文はセミコロン ; で終わります。
fn main() { let x = 5; let y = 10; println!("{}", x + y);}実行結果:
15必要な場所にセミコロンを書き忘れるのは、初心者がもっともよくやるミスのひとつです。でも心配はいりません。コンパイラがその場所をはっきり指摘してくれます。
式:値を返すコード
Section titled “式:値を返すコード”Rustのコードは2種類の部品でできています。この違いは、ほとんどの言語よりもRustで大きな意味を持ちます。
- 文(statement)は、何かをするけれど、値は返しません。
let x = 5;は文です。 - 式(expression)は、値を生み出します。
5、x + 1、x * 2はどれも式です。
多くの人が驚くのはここからです。波かっこ { } で囲んだコードのブロックも式なのです。ブロックの値は、セミコロンを付けずに書いた最後の行になります。
fn main() { let x = 5; let y = { let doubled = x * 2; // ブロックの中の文 doubled + 1 // セミコロンなし:これがブロックの値になる }; println!("y は {y} です");}実行結果:
y は 11 ですブロックは中の文を実行し、そのあと doubled + 1、つまり 11 を返します。それが y になります。閉じかっこ } のあとにセミコロンがあることにも注目してください。let y = ...; の行全体は、やはり文なのです。
doubled + 1 のあとにセミコロンを付けると、それはブロックの値ではなくなります。するとブロックは「何もない」値(Rustでは () と書きます)を返し、println! はそれを表示できないので、コンパイルが通らなくなります。この「最後の行にはセミコロンを付けない」というルールは、まさに関数が値を返すしくみそのものです。関数のページや、式としての if でもまた出てきます。
マクロと !
Section titled “マクロと !”println! をよく見てください。最後のビックリマークは打ち間違いではありません。! は、これが普通の関数ではなくマクロ(macro)であることを表しています。
マクロについて、今は完全に理解しなくて大丈夫です。覚えておいてほしいのはこれだけです。! が付いていたら、それはマクロです。今のところ使うのは、テキストを表示する println! だけです。
fn main() { println!("これはマクロの呼び出しです");}{} で値を表示する
Section titled “{} で値を表示する”println! の中にある波かっこ {} はプレースホルダーです。テキストのあとに渡した値が、ここに順番に埋め込まれます。
fn main() { let name = "Ferris"; let age = 10; println!("{}は{}歳です", name, age);}実行結果:
Ferrisは10歳です波かっこの中に変数名を直接書くこともできます。こちらのほうがすっきり読めることが多いです。
println!("{name}は{age}歳です");空白とインデント
Section titled “空白とインデント”RustはPythonのようにインデントを気にしません。ブロックの始まりと終わりは、波かっこ { } で判断します。インデントは、人間がコードを読みやすくするためのものです。
とはいえ、コミュニティには標準のスタイルがあり、Rustにはそれを自動で適用してくれるツールが付いています。
cargo fmtcargo fmt を実行すると、コードが公式のスタイルに整形されます。使う習慣をつけておきましょう。
コードの中に、Rustが無視するメモを書いておくことができます。これをコメントと呼び、// で始めます。
fn main() { // これはコメント。Rustは読み飛ばす println!("こんにちは!"); // 行の最後にもコメントを書ける}コメントについては、次のページでもっと詳しく説明します。
1. 計算式を表示しよう
Section titled “1. 計算式を表示しよう”a = 7 と b = 3 の2つの変数を作り、7 + 3 = 10 と表示してください。足し算はRustにやらせましょう。ヒント:println! には {} のプレースホルダーをいくつも書けます。テキストのあとに並べた値で、順番に埋められます。
解答を見る
fn main() { let a = 7; let b = 3; println!("{} + {} = {}", a, b, a + b);}実行結果:
7 + 3 = 102. 合計を計算するブロック
Section titled “2. 合計を計算するブロック”あるお店で、1個4円の商品を3個買い、送料が2円かかります。{ } のブロックを使って total を計算してください。ブロックの中で subtotal を作り、subtotal + 2 を返します。合計: 14 と表示しましょう。ヒント:ブロックの最後の行には、セミコロンを付けないでください。
解答を見る
fn main() { let price = 4; let quantity = 3; let total = { let subtotal = price * quantity; subtotal + 2 // 送料 }; println!("合計: {total}");}実行結果:
合計: 14- プログラムはすべて
main関数から始まります。 - コードは波かっこ
{ }の中に書き、ほとんどの文は;で終わります。 - 文は何かをし、式は値を生み出します。ブロックの最後の行に
;がなければ、それがブロックの値になります。 - (
println!のように)!が付いていたら、それはマクロです。 println!の中の{}は、渡した値で埋められるプレースホルダーです。- インデントは読みやすさのためのものです。
cargo fmtで自動整形できます。
理解度チェック
Section titled “理解度チェック”理解度チェック
1. Rustのプログラムで、main 関数の特別な点は何ですか?
2. println のあとに付いている ! は何を意味しますか?
3. let y = { let a = 2; a + 1 }; のあと、y の値はいくつですか?
スコア: 0 / 3
さらに詳しく
Section titled “さらに詳しく”- Hello, World! — The Rust Programming Language 日本語版:「Rustプログラムの解剖」の節で、
fn main、println!、セミコロンを公式に解説しています。 - 関数 — The Rust Programming Language 日本語版:「文と式」の節に、ブロックを含めた文と式の違いの例がさらにあります。
- Hello World — Rust by Example 日本語版:小さな実行できるプログラムと、
rustcで直接コンパイルする方法です。 - 式 — Rust by Example 日本語版:ブロックを値として使う短い例と、最後にセミコロンを付けるとどうなるかを紹介しています。
- Statements and expressions — The Rust Reference(英語):正確で形式的なルールです。あとで興味がわいたときにどうぞ。