【Go言語入門】3.ループ・条件分岐についてさくっと学ぶ

今回はループと条件分岐。他の言語と被っている箇所は多いけど、プログラミングの全般的な復習になるのであえて丁寧にキャッチアップします。

前回の記事

ループ

For, While?

こちらも変数同様、他の言語と書き方に若干の違いがあります。

package main

import (
  "fmt"
)

func main() {
  sum := 0
  for i := 0; i < 10; i++ {
    sum += i
  }
  fmt.Println(sum)
}

// >>> 45

CやJavaScriptでは括弧は常に書いてきて、Pythonでは括弧は必要ないと言うように一貫性があったので、中括弧は書くのに小括弧は書かないってなんか違和感がすごいです。

その代わりというと変かも知れませんが、Goはforに一貫性を持っており、

例えば

for ; sum < 100; sum++ {
  sum += sum
}

とか

for ; sum < 100; {
  sum += sum
}

こんな書き方でもオッケーになります。

あえてこのような書き方にすることはないと思いますが、

for sum < 100 {
  sum += sum
}

このようにWhileと同じ形にまですることができます。

それ故GoにはWhile文が存在しません。

そういえば最近Whileって使ってないな・・・

さらに省略すると、

sum := 0
for {
  sum += sum
}

無限ループになります。

条件分岐

If – Then – Else

公式の方では一瞬??となったので、色々試してみました。

package main

import (
  "fmt"
  "math"
)

func pow(x, n, lim float64) float64 {
  if v := math.Pow(x, n); v < lim {
    return v
  }
  return lim
}

func main() {
  fmt.Println(
    pow(3, 2, 10),
    pow(3, 3, 20),
  )
}

こちらはA Tour of Goの写経です。

要するにif文でもfor文同様条件の前に簡単にステートメントが書けるようです。

どんな場面で有効的なのかすぐには思いつきませんが、条件のためだけに用意していた判定関数・変数(isValidみたいな)とかをブロックと統合させるとスマートになるのかな?

もちろんよく知られているような使い方もできます。

package main

import (
  "fmt"
)

func main() {
  sum := 50
  if sum < 50 {
    fmt.Println("if", sum)
  } else if sum < 100 {
    fmt.Println("else if", sum)
  } else {
    fmt.Println("else", sum)
  }
}

ちなみに

package main

import (
  "fmt"
)

func main() {
  sum := 49
  if sum++; sum < 50 {
    fmt.Println("if", sum)
  }
  fmt.Println(sum)
}

これは条件判定の前にインクリメントしているのでif内の処理は実行されないのですが、変数sumは最終的に50になります。

当然といえば当然ですが、forもifもブロック外にスコープを持つ変数をステートメントに置く時は注意が必要です。

また、

package main

import (
  "fmt"
)

func main() {
  sum := 50
  if v := sum; sum < 50 {
    sum += v
  } else {
    sum -= v
  }
  fmt.Println(sum)
}

上記のように、条件前に宣言した変数のスコープの範囲はシーケンス内で有効なので、elseブロック内でも使用できます。

Switch

ifやforとステートメントや真偽判定などの順序は同じです。

package main

import (
  "fmt"
)

func main() {
  color := "red"
  switch color {
  case "blue":
    fmt.Println("color is blue")
  case "red":
    fmt.Println("color is red")
  case "green":
    fmt.Println("color is green")
  default:
    fmt.Println("color is unknown")
  }
}

雑ですが、変数colorについて評価しているswitch文です。

他の言語と比べて変わったところといえば上から下へcase評価していき、条件にあったcase内が実行されると、後に続くcaseは実行されません。

自動的breakが挿入されているイメージですね。

そのため、if – then – elseの代用が可能です。

package main

import (
  "fmt"
)

func main() {
  color := "red"
  switch {
  case color == "blue":
    fmt.Println("color is blue")
  case color == "red":
    fmt.Println("color is red")
  case color == "green":
    fmt.Println("color is green")
  default:
    fmt.Println("color is unknown")
  }
}

こちらは最初に示したソースコードと同等です。

簡潔にまとめられる時はswitch文のほうが良いのかも知れません。

今回はとりあえずここらへんで。

Goプログラミング実践入門