Go言語の論理演算子、ちゃんと使いこなせていますか?
プログラミングを学び始めると、if
文などで&&
や||
、!
といった記号に出会いますよね。「これって何だっけ…?」となる方もいるかもしれません。
それらは「論理演算子」といって、条件を組み合わせるときに使う、プログラミングの縁の下の力持ちなんです。
この記事では、Go言語の論理演算子の基本から、具体的な使い方、そしてちょっとした注意点まで、どこよりも分かりやすく解説していきます。
この記事で学べること
- 論理演算子のキホン的な考え方
- Go言語で使うAND(&&), OR(||), NOT(!)って何?
- 実際のコードでの書き方と使い方サンプル
- 論理演算子を使うときの注意点(落とし穴)
Go言語の論理演算子とは?
まず、「論理演算子」って一体何者なのか、その基本から見ていきましょう。
簡単に言うと、論理演算子は複数の条件を組み合わせたり、条件の意味をひっくり返したりするための道具です。プログラミングでは、「もし〇〇で、かつ、△△だったら」とか、「もし□□、または、××だったら」みたいに、いくつかの条件をまとめて判断したい場面がたくさんありますよね。
例えば、「もし、雨が降っていて(条件1)、かつ、傘を持っていなかったら(条件2)、傘を買う」というような処理を考えます。この「かつ」の部分を担当するのが論理演算子(この場合はAND演算子)なんです。
このように、条件分岐(if
文など)を使ってプログラムの流れをコントロールする上で、論理演算子はなくてはならない存在なのです。まるで、条件と条件をつなぐ接着剤みたいなもの、とイメージすると分かりやすいかもしれませんね。
Go言語で使われる主要な論理演算子の種類
Go言語でよく使う論理演算子は、主に以下の3つです。それぞれの記号と意味をしっかり覚えましょう!
&&
(論理積 AND)意味:「かつ」 (両方の条件が正しくないとダメ!)
||
(論理和 OR)意味:「または」 (どちらか一方でも条件が正しければOK!)
!
(否定 NOT)意味:「〜ではない」 (条件の正誤をひっくり返す!)
たった3つなので、意外とすぐに覚えられますよ。では、次からそれぞれの使い方を詳しく見ていきましょう。
論理積(AND):「&&」の使い方
まずは論理積(AND)の&&
から。これは、2つの条件が両方とも正しい(真: true)場合にだけ、全体の結果も正しい(真: true)となる演算子です。「A かつ B」という意味ですね。
例えば、「試験の点数が80点以上で、かつ、出席率が90%以上なら合格」という条件を考えてみます。これをGo言語のコードで書くと、こんな感じになります。
書き方
if 条件1 && 条件2 { // 条件1 と 条件2 の両方が true の場合にここの処理が実行される }
ソースコード
package main import "fmt" func main() { score := 85 attendance := 95 // 点数が80点以上 かつ 出席率が90%以上 かどうか if score >= 80 && attendance >= 90 { fmt.Println("合格です!おめでとう!") } else { fmt.Println("残念、不合格です。") } score = 75 // 点数を変えてみる if score >= 80 && attendance >= 90 { fmt.Println("合格です!おめでとう!") } else { fmt.Println("残念、不合格です。(点数不足)") } }
ソースコードの表示結果:
合格です!おめでとう! 残念、不合格です。(点数不足)
最初の例では、score >= 80
(85点なのでtrue) と attendance >= 90
(95%なのでtrue) の両方がtrueなので、if
文の中の処理が実行されました。
2番目の例では、score >= 80
(75点なのでfalse) となったため、&&
の右側(出席率)がたとえtrueでも、全体としてはfalseとなり、else
の中の処理が実行されています。
論理和(OR):「||」の使い方
次は論理和(OR)の||
です。これは、2つの条件のうち、どちらか一方でも正しい(真: true)なら、全体の結果も正しい(真: true)となる演算子です。「A または B」という意味ですね。もちろん、両方とも正しくてもOKです。
例えば、「週末である、または、祝日であるなら、会社はお休み」という条件を考えてみましょう。
書き方
if 条件1 || 条件2 { // 条件1 または 条件2 のどちらか一方(あるいは両方)が true の場合にここの処理が実行される }
ソースコード
package main import "fmt" func main() { isWeekend := true isHoliday := false // 週末 または 祝日 かどうか if isWeekend || isHoliday { fmt.Println("やったー!お休みだ!") } else { fmt.Println("お仕事(学校)がんばろう...") } isWeekend = false // 平日にしてみる if isWeekend || isHoliday { fmt.Println("やったー!お休みだ!") } else { fmt.Println("お仕事(学校)がんばろう...") } }
ソースコードの表示結果:
やったー!お休みだ! お仕事(学校)がんばろう...
最初の例では、isWeekend
がtrueなので、isHoliday
がfalseでも、少なくとも一方がtrueなのでif
文の中が実行されました。2番目の例では、isWeekend
もisHoliday
も両方falseなので、else
の中が実行されていますね。&&
とは違って、どちらか片方でも当てはまれば良い、というのがポイントです。
否定(NOT):「!」の使い方
最後は否定(NOT)の!
です。これは他の2つと違って、1つの条件に対して使います。その役割はシンプルで、条件の真偽(true/false)をひっくり返すことです。
trueの条件に!
をつけるとfalseに、falseの条件に!
をつけるとtrueになります。「〜ではない」という意味合いですね。
例えば、「ログインしていない(isLoggedIn
がfalse)なら、ログインを促すメッセージを出す」という場合に使えます。
書き方
if !条件 { // 条件が false の場合にここの処理が実行される }
ソースコード
package main import "fmt" func main() { isLoggedIn := false // ログインしていない (isLoggedIn が false) かどうか if !isLoggedIn { fmt.Println("ようこそ!まずはログインしてくださいね。") } else { fmt.Println("ログイン済みです。") } isLoggedIn = true // ログイン状態にする if !isLoggedIn { fmt.Println("ようこそ!まずはログインしてくださいね。") } else { fmt.Println("ログイン済みです。") } }
ソースコードの表示結果:
ようこそ!まずはログインしてくださいね。 ログイン済みです。
最初の例では、isLoggedIn
がfalseなので、!isLoggedIn
はtrueとなり、if
文の中が実行されました。2番目の例では、isLoggedIn
がtrueなので、!isLoggedIn
はfalseとなり、else
の中が実行されました。真偽値を反転させる役割、しっかり掴めましたか?
Go言語の論理演算子の実践的な使い方
基本的な使い方がわかったところで、もう少し実践的な例を見てみましょう。論理演算子は、組み合わせて使うことで、より複雑な条件を表現できるようになります。
例えば、「年齢が20歳以上で、かつ、(会員であるか、または、特別招待者である)」という条件を考えてみましょう。これをコードにすると、以下のようになります。
ソースコード
package main import "fmt" func main() { age := 22 isMember := false isSpecialGuest := true // 年齢が20歳以上 かつ (会員 または 特別招待客) かどうか if age >= 20 && (isMember || isSpecialGuest) { fmt.Println("入場可能です。どうぞお楽しみください!") } else { fmt.Println("申し訳ありません、入場条件を満たしていません。") } isSpecialGuest = false // 特別招待客でもなくしてみる if age >= 20 && (isMember || isSpecialGuest) { fmt.Println("入場可能です。どうぞお楽しみください!") } else { fmt.Println("申し訳ありません、入場条件を満たしていません。") } }
ソースコードの表示結果
入場可能です。どうぞお楽しみください! 申し訳ありません、入場条件を満たしていません。
この例では、まず(isMember || isSpecialGuest)
の部分が評価されます。最初の例ではisSpecialGuest
がtrueなので、この括弧の中はtrueになります。そして、age >= 20
(22歳なのでtrue) と &&
で結合されるので、全体としてtrueとなり、入場可能と判定されます。
2番目の例では、isMember
もisSpecialGuest
もfalseなので、括弧の中がfalseになります。そのため、age >= 20
がtrueであっても、&&
で結合された結果はfalseとなり、入場不可と判定されます。
このように、&&
と||
、そして括弧()
を組み合わせることで、色々な条件を柔軟に作ることができるんです。
if文での基本的な活用例
論理演算子が一番活躍するのは、やはりif
文やif-else if-else
文を使った条件分岐の場面でしょう。プログラムは、状況に応じて実行する処理を変える必要があるため、条件分岐は必須テクニックです。
簡単な例から見てみましょう。「点数に応じて成績を表示する」プログラムです。
ソースコード
package main import "fmt" func main() { score := 75 if score >= 90 { fmt.Println("成績: 優") } else if score >= 70 && score < 90 { // 70点以上 かつ 90点未満 fmt.Println("成績: 良") } else if score >= 50 && score < 70 { // 50点以上 かつ 70点未満 fmt.Println("成績: 可") } else { // それ以外(50点未満) fmt.Println("成績: 不可") } }
ソースコードの表示結果
成績: 良
この例では、else if
の部分で&&
を使って、「〇〇点以上 かつ ××点未満」という範囲を指定しています。このように論理演算子を使うことで、細かな条件に応じてプログラムの処理の流れを制御することができます。
演算子の優先順位に注意
複数の論理演算子や、比較演算子(>
, <
, ==
など)を一つの式の中に書く場合、計算される順番(優先順位)が決まっています。これを意識しないと、思った通りの動きにならないことがあるので注意が必要です。
Go言語の論理演算子の優先順位は、強い順に以下のようになっています。
!
(NOT)&&
(AND)||
(OR)
つまり、!
が一番先に計算され、次に&&
、最後に||
が計算されます。
例えば、a || b && c
という式があった場合、これはa || (b && c)
と同じ意味になります。&&
の方が||
より優先度が高いからですね。もし(a || b) && c
という意味で計算させたい場合は、括弧()
を使って明示的に順番を指定する必要があります。
ソースコード例
package main import "fmt" func main() { a := true b := false c := true // 優先順位: && が || より先 // b && c は false && true で false // a || false は true || false で true result1 := a || b && c fmt.Println("括弧なし:", result1) // true // 括弧で || を先に計算させる // (a || b) は true || false で true // true && c は true && true で true (この例では結果は同じだが...) result2 := (a || b) && c fmt.Println("括弧あり:", result2) // true // 違う例 x := false y := true z := true // y && z は true && true で true // x || true は false || true で true result3 := x || y && z fmt.Println("括弧なし:", result3) // true // (x || y) は false || true で true // true && z は true && true で true (この例でも結果は同じ...) // 結果が変わる例! val1 := true val2 := false val3 := false // val2 && val3 は false && false で false // val1 || false は true || false で true fmt.Println("val1 || val2 && val3 =", val1 || val2 && val3) // true // (val1 || val2) は true || false で true // true && val3 は true && false で false fmt.Println("(val1 || val2) && val3 =", (val1 || val2) && val3) // false }
ソースコードの表示結果
括弧なし: true 括弧あり: true 括弧なし: true val1 || val2 && val3 = true (val1 || val2) && val3 = false
最後の例で結果が変わりましたね!このように、優先順位を意識しないと思わぬ結果になることがあります。ややこしいな、と感じたら、括弧を使って計算の順番をはっきりと示すのが一番安全で、コードも読みやすくなりますよ!
Go言語の論理演算子を使う上での重要な注意点
Go言語の論理演算子、特に&&
と||
には、「短絡評価(ショートサーキット評価)」と呼ばれる、ちょっと面白い(そして注意が必要な)性質があります。
これはどういうことかというと…
&&
の場合左側の条件を評価して、それが
false
だったら、右側の条件は評価せずに、式全体の結果をfalse
と確定させます。(だって、片方がfalseなら、もう片方がどうであれ結果はfalseになりますよね?)||
の場合左側の条件を評価して、それが
true
だったら、右側の条件は評価せずに、式全体の結果をtrue
と確定させます。(だって、片方がtrueなら、もう片方がどうであれ結果はtrueになりますよね?)
なぜこんな仕組みがあるかというと、無駄な計算を省いてプログラムを少しでも速くするためなんです。賢い!
ただ、これを知らないと、ちょっと困ったことになるケースもあります。例えば、右側の条件に「何かをする」(関数を呼び出すなど)処理が含まれている場合、左側の条件次第ではその処理が実行されない可能性がある、ということです。
短絡評価(ショートサーキット)とは?
短絡評価の動きを、もう少し具体的にコードで見てみましょう。
&&
の短絡評価の例
package main import "fmt" // 左側のチェック用関数(実行されたらメッセージ表示) func checkLeft() bool { fmt.Println("...左側をチェック中...") return false // ここを true にすると右側も評価される } // 右側のチェック用関数(実行されたらメッセージ表示) func checkRight() bool { fmt.Println("...右側をチェック中...") return true } func main() { fmt.Println("&& の評価を開始します:") if checkLeft() && checkRight() { fmt.Println("結果: true") } else { fmt.Println("結果: false") } fmt.Println("&& の評価を終了しました。") }
ソースコードの表示結果
&& の評価を開始します: ...左側をチェック中... 結果: false && の評価を終了しました。
checkLeft()
がfalse
を返したので、「...右側をチェック中...」というメッセージは表示されませんでしたね。右側のcheckRight()
関数は呼び出されなかった(評価がスキップされた)わけです。
||
の短絡評価の例
package main import "fmt" // 左側のチェック用関数(実行されたらメッセージ表示) func checkLeft() bool { fmt.Println("...左側をチェック中...") return true // ここを false にすると右側も評価される } // 右側のチェック用関数(実行されたらメッセージ表示) func checkRight() bool { fmt.Println("...右側をチェック中...") return true } func main() { fmt.Println("|| の評価を開始します:") if checkLeft() || checkRight() { fmt.Println("結果: true") } else { fmt.Println("結果: false") } fmt.Println("|| の評価を終了しました。") }
ソースコードの表示結果
|| の評価を開始します: ...左側をチェック中... 結果: true || の評価を終了しました。
今度はcheckLeft()
がtrue
を返したので、「...右側をチェック中...」は表示されず、右側の評価がスキップされました。
このように、短絡評価は無駄な評価をスキップする賢い仕組みですが、右側の式で何か処理を行うことを期待している場合は、意図通りに動かない可能性があるので、頭の片隅に置いておきましょう。
特に、エラーチェックなどで「値が存在する場合だけ、その値を使って何かする」といったコード(例: if ptr != nil && ptr.Value > 0
)では、この短絡評価がうまく利用されています。
【まとめ】Go言語の論理演算子をマスターして条件分岐を使いこなそう!
お疲れ様でした!今回は、Go言語の論理演算子について、基本から使い方、注意点までガッツリ解説しました。
ポイントを振り返ってみましょう。
- 論理演算子は条件を組み合わせるための道具(
&&
,||
,!
) &&
(AND) は「かつ」(両方trueでtrue)||
(OR) は「または」(どちらかtrueでtrue)!
(NOT) は「ではない」(true/falseを反転)- 複数の演算子を使うときは優先順位に注意(
!
>&&
>||
)。迷ったら括弧()
を使おう! &&
と||
には短絡評価という性質があることを知っておこう。
論理演算子は、プログラムに「考える力」を与えるための基礎となる部分です。これをしっかりマスターすれば、より複雑で気の利いたプログラムが作れるようになりますよ!
今回学んだことを活かして、どんどんコードを書いて、Go言語のプログラミングをもっと楽しんでくださいね!応援しています!
【関連記事】 Go言語とは?特徴・できること・将来性
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。