Rustのif/elseとは?条件分岐の基本
プログラミングって、コンピュータに指示を出すことですよね。でも、いつも同じ指示だけじゃつまらない!状況によって違う動きをしてほしい時、どうすればいいんでしょう?
そこで登場するのが条件分岐です。まるで「もし雨が降っていたら傘を持っていく、そうでなければ持っていかない」みたいに、プログラムにも条件によって動きを変えさせる仕組みが必要なんです。
Rust言語では、この条件分岐の基本的な役割を担うのが`if`文と`else`文になります。これらを使うことで、プログラムが状況に応じて賢く判断し、適切な処理を実行できるようになるんですよ。
Rustのif/else文の基本的な書き方
さっそく、Rustで`if`や`else`をどう書くのか見ていきましょう!基本の形さえ覚えれば、意外と簡単ですよ。
Rustの`if`文で大事なのは、条件式の結果が必ず`true`(真)か`false`(偽)のどちらかになること、そして処理を書く部分は波括弧`{}`で囲む必要があることです。この2点をしっかり押さえておきましょう。
if文のみの書き方
まずは一番シンプルな形、`if`だけを使うパターンです。「もし、この条件が成り立ったら、この処理をしてね」という場合に使います。
fn main() { let number = 7; // numberが5より大きい場合にメッセージを表示 if number > 5 { println!("{} は5より大きいですよ!", number); } println!("ここのメッセージはif文とは関係なく表示されます。"); }
上のコードを実行すると、こんな感じになります。
7 は5より大きいですよ! ここのメッセージはif文とは関係なく表示されます。
変数`number`は7なので、`number > 5`という条件は`true`(真)になります。だから、`if`ブロックの中の`println!`が実行されたわけですね。
もし`number`が3だったら、`number > 5`は`false`(偽)になるので、`if`ブロックの中は実行されず、最後の`println!`だけが表示されます。
このように、条件が`true`の時だけ特定の処理を実行したい場合に`if`文だけを使います。
if文とelse文を組み合わせた書き方
次に、「もし条件が成り立ったらAの処理、そうでなければBの処理をしてね」という、2つの選択肢があるパターンです。これには`if`と`else`をセットで使います。
fn main() { let score = 75; // scoreが60点以上かどうかでメッセージを変える if score >= 60 { println!("点数: {} 点、合格です!おめでとう!", score); } else { println!("点数: {} 点、残念ながら不合格です。次回頑張ろう!", score); } }
これを実行してみましょう。
点数: 75 点、合格です!おめでとう!
`score`は75なので、`score >= 60`の条件は`true`(真)です。そのため、`if`ブロックの中身が実行されました。
もし`score`が50だったらどうでしょう?`score >= 60`は`false`(偽)になるので、今度は`else`ブロックの中身が実行され、「不合格です」のメッセージが表示されるはずです。
このように、`if`と`else`を組み合わせると、条件に応じて必ずどちらか一方の処理が実行されるようになります。これが一番よく使う条件分岐の形かもしれませんね。
複数の条件を扱う - Rustのelse ifの使い方
選択肢が「AかBか」の2択だけじゃなく、「AかBかCか、それともDか…」みたいに、もっとたくさんある場合もありますよね。
そんな時は`else if`の出番です!`if`と`else`の間に`else if`を挟むことで、条件をいくつも追加していくことができます。
fn main() { let temperature = 25; if temperature > 30 { println!("すごく暑い!エアコンをつけましょう。"); } else if temperature > 20 { // 30度以下で、かつ20度より高い場合 println!("ちょうど良い気温ですね。快適!"); } else if temperature > 10 { // 20度以下で、かつ10度より高い場合 println!("少し肌寒いかも。上着があるといいですね。"); } else { // それ以外(10度以下)の場合 println!("寒い!暖房が必要かも。"); } }
`else if`を使う時の流れは、
- まず最初の`if`の条件をチェック。`true`ならそのブロックを実行して終わり。
- `if`が`false`なら、次の`else if`の条件をチェック。`true`ならそのブロックを実行して終わり。
- さらに`else if`があれば、同様にチェックしていく。
- どの`if`や`else if`の条件も`false`だったら、最後の`else`ブロックを実行する(`else`があれば)。
else ifの構文と具体例
さっきの温度の例を実際に動かしてみましょう。`temperature`が25の場合です。
ちょうど良い気温ですね。快適!
実行結果はこうなります。流れを追ってみましょう。
- `temperature > 30` (25 > 30) → `false`なので次へ。
- `temperature > 20` (25 > 20) → `true`! なので、この`else if`ブロック内の`println!`が実行されます。
- ここで条件が満たされたので、これ以降の`else if`や`else`はチェックされずに`if`文全体が終了します。
もし`temperature`が5だったらどうなるでしょう?
寒い!暖房が必要かも。
今度はこうなります。
- `temperature > 30` (5 > 30) → `false`
- `temperature > 20` (5 > 20) → `false`
- `temperature > 10` (5 > 10) → `false`
- どの条件にも当てはまらなかったので、最後の`else`ブロックが実行されます。
Rustの特徴 - if/elseは「式」である
さて、ここからがRustのちょっと面白いところです!
多くのプログラミング言語では、`if`/`else`は「文(Statement)」として扱われます。文というのは、コンピュータに何かをさせる「命令」のようなものです。例えば、「この値を出力しろ!」とか、「この計算をしろ!」とかですね。
ところがRustでは、`if`/`else`は「式(Expression)」なんです! 式というのは、評価されると何らかの「値」を生み出すものを指します。例えば、`5 + 3`という式は評価されると`8`という値になりますよね。
「`if/else`が値を返すってどういうこと?」って思いますよね。これが分かると、Rustでより簡潔でスマートなコードが書けるようになりますよ!
「文」と「式」の違いとif式の使い方
もう少し「文」と「式」の違いを見てみましょう。
- 文 (Statement): 何かの動作を実行する命令。それ自体が値を持つわけではない。例:`let x = 5;` (変数`x`に5を束縛するという動作)
- 式 (Expression): 評価されると値を返すもの。例:`5 + 3` (評価されると`8`になる), `x * 2` (評価されると`x`の値の2倍になる)
Rustでは、`if/else`の各ブロック(`{}`で囲まれた部分)の最後に書かれた式が、そのブロックの返す値になります。
そして、`if/else`全体も式なので、条件に応じてどちらかのブロックの値が`if/else`全体の評価結果として返ってくる、という仕組みなんです。
`if`/`else`が値を返すから、その結果を直接変数に入れたりできる、と考えてみてください。
if式を変数に代入する(サンプルコードと解説)
「`if`が式である」ことのメリットが一番分かりやすいのが、`let`と一緒に使う場面です。
fn main() { let age = 20; // 年齢に応じてメッセージを決定し、変数`message`に代入 let message = if age >= 20 { "あなたは成人です。" // 条件がtrueの場合、この文字列が返る } else { "あなたは未成年です。" // 条件がfalseの場合、この文字列が返る }; // if式全体の結果がmessageに入る println!("{}", message); }
これを実行すると、`age`は20なので、結果はこうなります。
あなたは成人です。
見てください!`if age >= 20 { ... } else { ... }`の部分全体が一つの式として扱われ、その結果(この場合は文字列`"あなたは成人です。"`)が直接`let message = ...`の右辺となり、変数`message`に代入されていますよね。
もし`if`が文だったら、こんな風に書くことはできません。通常は、先に`let mut message;`のように変数を宣言しておいて、`if`ブロックと`else`ブロックの中でそれぞれ`message = "..."`のように代入する必要があるでしょう。
それと比べると、`if`を式として使えるRustの書き方は、とてもスッキリしていて読みやすいと思いませんか?
ただし、この書き方をする際は、`if`ブロックと`else`ブロック(もし`else if`があればそれらも全て)が返す値の型が同じである必要があります。
例えば、片方が数値を返し、もう片方が文字列を返すような書き方はできません。また、`let`で受ける場合は`else`を省略することもできません(理由は次の注意点で!)。
Rustのif/else利用時の注意点とベストプラクティス
`if`/`else`は基本的な機能ですが、特にRustの「式」としての側面を考えると、いくつか気をつけたいポイントがあります。
これを押さえておけば、無用なエラーを避けることができます。
型の不一致と`else`の省略エラー(具体例と対策)
`if`を式として使う(例えば`let`で結果を受け取る)場合に、初心者がつまずきやすいのが次の2点です。
- 各ブロックが返す値の型が違う
- `let`で受ける時に`else`を省略してしまう
まず、型の不一致エラーから見てみましょう。
// エラーになる例: ifブロックは数値、elseブロックは文字列を返そうとしている fn main() { let condition = true; let result = if condition { 100 // 数値 (i32型) } else { "hello" // 文字列 (&str型) }; // ↑ このコードはコンパイルエラーになります! // error[E0308]: `if` and `else` have incompatible types println!("{}", result); }
Rustコンパイラは賢いので、「`if`と`else`で型が違うよ!」としっかり教えてくれます (`incompatible types`というメッセージが出ます)。`if`式全体が一つの値として評価されるためには、どの分岐を通っても同じ型の値が返ってくる必要があるのです。
この例だと、数値を返すなら`else`側も数値を、文字列を返すなら`if`側も文字列を返すように修正しないといけません。
次に、`else`の省略エラーです。
// エラーになる例: letで受けるのにelseがない fn main() { let condition = false; let result = if condition { 10 // conditionがtrueなら10 }; // conditionがfalseだったら、何をresultに入れればいいの? // ↑ このコードもコンパイルエラーになります! // error[E0317]: `if` may be missing an `else` clause println!("{}", result); }
`let result = ...`のように変数に結果を代入しようとしているのに、`if`の条件が`false`だった場合に返す値が指定されていません。これでは変数`result`に何を入れたら良いか決まらないですよね?
そのため、`if`を式として使い、その結果を変数に入れるような場合は、必ず`else`ブロックも記述して、条件が`false`だった場合に返す値を指定してあげる必要があります。コンパイラも`missing an else clause`(else節がないよ)と教えてくれます。
これらのエラーは、Rustがプログラムの安全性を重視している証拠でもあります。コンパイラのエラーメッセージをよく読んで、落ち着いて修正していきましょう!
【まとめ】Rustのif/elseを理解して活用しよう
お疲れ様でした!この記事では、Rustの条件分岐の基本である`if`/`else`文について、その使い方を順を追って見てきました。
- `if`で条件を指定し、`{}`内に処理を書く基本形
- `else`で「そうでなければ」の処理を追加できること
- `else if`でたくさんの選択肢を扱えること
- Rust特有の、`if`/`else`が値を返す「式」であるという考え方
- 式として使う場合の注意点(型の統一、`else`の必要性)
これらのポイントを押さえれば、Rustで状況に応じた処理を書くための基礎はバッチリです!
特に`if`が式であるという点は、慣れると本当に便利で、コードを簡潔にするのに役立ちます。
最初は少し戸惑う部分もあるかもしれませんが、実際にコードを書いて動かしてみるのが一番の近道です。ぜひ、この記事のサンプルコードを参考に、ご自身でも色々な条件分岐を試してみてくださいね。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。