【Go入門】A tour of Go 【Flow control statements】

A tour of Go のBasicsの続きです。
引き続き、他言語と違う箇所を中心にピックアップします。

Flow control statesment

for

for 初期化(変数宣言); 条件式; 後処理{}

セミコロンで3つのセクションに分かれる
セクションを()で括らない
後処理の{}は必要

for.go
package main

import “fmt”

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

条件式以外の記述は必須ではない
セミコロンも省略可なので他言語のwhileはforで記述

for-is-gos-while.go
for sum < 1000 {
sum += sum
}

条件式を省略すると無限ループになる

forever.go
package main

func main() {
for {
}
}

if

if 条件式 {true処理} else{false処理}

forと同じく条件式を()で括らない

if.go
package main

import (
“fmt”
“math”
)

func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + “i”
}
return fmt.Sprint(math.Sqrt(x))
}

func main() {
fmt.Println(sqrt(2), sqrt(-4))
}

xの平方根を文字列で出力する関数。xが負の場合、虚数になるので分岐

forと同様に、条件句の前で簡単な変数宣言もできる(スコープはif-else内)

if-with-a-short-statement.go
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf(“%g >= %g\n”, v, lim)
}
return lim

x^n(xのn乗)がlimを超えないときはそのまま、超えたらlimを返す

Exercise

exercise-loops-and-functions.go
package main

import (
“fmt”
“math”
)

func Sqrt(x float64) (float64, int) {
z:=1.0
var delta float64
for i := 1; i <= 30; i++ {
delta = (z*z – x)/(2*z)
if math.Abs(delta) < 0.1 {
return z, i
}
z -= delta
}
return z, 30
}

func main() {
fmt.Println(Sqrt(4))
}

30回ニュートン法による近似を行う関数。30回未満で変動幅が0.1以下になった場合、その回数を出力します。Exerciseは10回未満かどうかを判定する内容なので、あとはbooleanで出力したり、近似回数を変えてみたりしても楽しい

switch

switch 変数宣言; 変数{case 値: 処理…, default: 処理…}

Goでは条件が一致したcaseでbreakし、他のcaseは実行されない
caseは定数でなくてもよく、整数以外も可

switch.go
package main

import (
“fmt”
“runtime”
)

func main() {
fmt.Print(“Go runs on “)
switch os := runtime.GOOS; os {
case “darwin”:
fmt.Println(“OS X.”)
case “linux”:
fmt.Println(“Linux.”)
default:
// freebsd, openbsd,
// plan9, windows…
fmt.Printf(“%s.\n”, os)
}
}

runtime.goosは実行しているOSの種類を返す。
https://golang.org/pkg/runtime/#pkg-constants

defer

defer 関数

関数を渡すとdeferの呼び出し元の関数の処理が終わったあとに、遅延して処理する。

deferに渡す関数の引数はその場で評価する
複数の関数をdeferでスタックさせた場合、実行はlast-in-first-out

defer.go
package main

import “fmt”

func main() {
x := 4
defer fmt.Println(x)
x += 1
defer fmt.Println(x)
x += 1
fmt.Println(x)
}
->
6
5
4

x=6の次に最後にスタックしたx=5から出力される。