Edited at

golangを基礎から学ぶ 制御構造編

More than 3 years have passed since last update.


制御構造

いくつかの制御構造、いわゆる、if、 while、for、 foreach、switch などについて。


if

条件部、丸括弧不要。

本件部、波括弧必要。

x := 3

if x > 0 {
fmt.Println(x)
}

初期化ステートメントを記述できるため、そこでローカル変数の準備を行うのが一般的。

if err := file.Chmod(0664); err != nil {

log.Stderr(err)
return err
}

少し複雑な条件1

丸括弧使っていけないわけではない

x := 3

y := 4
if (x > 0 && y > 5) || (x > 0 && y > 0) {
fmt.Println(y)
}

少し複雑な条件2

elseif → ×

else if → ○

x := 3

y := 4
if (x > 0 && y > 5) || (x > 0 && y > 8) {
fmt.Println(y)
} else if x == 2 || y == 4 {
fmt.Println("elseif")
} else {
fmt.Println("else")
}

数値 0 の真(true)偽(false)をifで確かめたところ処理はエラーになった↓

non-bool 0 (type untyped number) used as if condition

go言語は真偽値の型をもっていて条件式はその型でなければいかんということで、0は整数型であって、真偽型ではないから以下の処理はコンパイルエラーになる。

if 0 {

fmt.Println("true")
} else {
fmt.Println("false")
}


for, while(golangにはない)

ループにはdoやwhileはなく、若干改良されたforループだけがある

whileに相当する形式

x := 100

for x > 0 {
x--
fmt.Println("Value of i is now:", x)
}

for ;; {...}

の書き方はいわゆる無限ループなので、条件を適切に扱う必要がある

do while やろうとするとこんな感じになる↓

for value := 0;; {

value++
fmt.Println(value)
if value % 6 == 0 {
break
}
}

典型的なfor

sum := 0

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

foreach 的な1

items := map[int]int{0:10 , 1:20}

for key, value := range items {
fmt.Println("key:", key, " value:", value)
}

foreach 的な2

連想配列で

commits := map[string]int{

"rsc": 3711,
"r": 2138,
"gri": 1908,
"adg": 912,
}
for key, value := range commits {
fmt.Println("key:", key, " value:", value)
}


switch

golangのswitchは多機能

ごく普通のswitch

数値型のものを引数にしてるなかで、他の型がcaseに指定するコンパイルエラーになる

i := 5

switch i {
case 4: fmt.Println("number 4")
case 5:fmt.Println("number 5")
case 6: fmt.Println("number 6")
//case i>7: fmt.Println("is > 7") //compile error as type int and bool don't match between case and switch
default: fmt.Println("default")
}

こちらは文字列ほ引数にしたswitch

s1 := "abcd"

s2 := "efgh"
switch s1 {
case s2: fmt.Println("the two strings are equal")
default: fmt.Println("the two strings are NOT equal") //since nothing else matches, the default block is executed
}

一つのcaseに複数の値を指定することもできる

j := 4

switch j {
case 1,3,5,7,9: fmt.Println(j, "is odd")
case 0,2,4,6,8: fmt.Println(j, "is even")
default: fmt.Println(j, "is not an integer between 0 and 9")
}

switch-caseのデフォルト動作はfallthroughではない

つまり、breakを書かなくても途中でcaseマッチしたら終了するということ

fallthroughステートメントを使うと、式switch(§式switch)の次のcase節の先頭のステートメントへ制御をうつす(この場合caseの条件はみない)

k := 6

switch k {
case 4: fmt.Println("was <= 4"); fallthrough;
case 5: fmt.Println("was <= 5"); fallthrough;
case 6: fmt.Println("was <= 6"); fallthrough;
case 7: fmt.Println("was <= 7"); fallthrough;
case 8: fmt.Println("was <= 8"); fallthrough;
default: fmt.Println("default case")
}

output

was <= 6

was <= 7
was <= 8
default case

if-elseチェーン的に書ける

num := 15

switch {
case num == 1:
fmt.Println(1)
case (num > 5 && num < 11) && (num > 5 && num < 16):
fmt.Println(2)
case (num > 5 && num < 11) || (num > 5 && num < 16):
fmt.Println(3)
default:
fmt.Println("default")
}


参考

The Go Programming Language

Tour Go