はじめてのGo―シンプルな言語仕様,型システム,並行処理

第2章 基本文法―覚えやすいコンパクトな言語仕様

この記事を読むのに必要な時間:およそ 9.5 分

変数

次は変数について説明します。例としてhello worldプログラムの出力メッセージを,messageというstringの変数に代入してみます。

var message string = "hello world"

func main() {
    fmt.Println(message)
}

変数の宣言は,varで始まり,次に変数名,最後が型です。型と変数名の順番を珍しく思うかもしれませんが,これがGoの特徴の一つです。

一度に複数の宣言と初期化

一度に複数宣言する場合は次のように記述することもできます。

var foo, bar, buz string = "foo", "bar", "buz"

一度に多くの変数を同じ型で宣言する場合は,varと2つ目以降の型を省略して,次のように書くこともできます。

var (
a string = "aaa"
b = "bbb"
c = "ccc"
d = "ddd"
e = "eee"
)

関数内部での宣言と初期化

変数宣言と初期化を関数の内部で行う場合は,varと型宣言を省略し,:=という記号を用いることができます。

func main() {
    // どちらの書き方も同じ意味
    // var message string = "hello world"
    message := "hello world"
    fmt.Println(message)
}

この書き方をした場合,変数の型は代入する値からコンパイラによって推論されます。今回は文字列を代入していることから,変数messageの型がstringであると推論されます。

定数

変数宣言のvarconstに変えると定数になります。

func main() {
    const Hello string = "hello"
    Hello = "bye" // cannot assign to Hello
}

定数宣言できる型は,組込み型のうちerror以外の型です。定数に対する再代入はコンパイルエラーになるため,実行前にミスを発見できます。

ゼロ値

変数を宣言し,明示的に値を初期化しなかった場合,変数はゼロ値というデフォルト値で初期化されます。ゼロ値は型ごとに決まっており,たとえばintのゼロ値は0であるため,次のコードは0を出力します。

func main() {
    var i int // iはゼロ値で初期化
    fmt.Println(i) // 0
}

型ごとのゼロ値は表2のようになります。

表2 型ごとのゼロ値

ゼロ値
整数型0
浮動小数点型0.0
boolfalse
string""
配列各要素がゼロ値の配列
構造体各フィールドがゼロ値の構造体
そのほかの型nil

nilは値がないことを表す値。ほかの言語におけるnullなどに相当する

if

Goでは,if文の条件部に丸括弧は必要ありません。

func main() {
    a, b := 10, 100
    if a > b {
        fmt.Println("a is larger than b")
    } else if a < b {
        fmt.Println("a is smaller than b")
    } else {
        fmt.Println("a equals b")
    }
}

なお,if文の処理が1行の場合に波括弧を省略可能な言語もありますが,Goではそうした省略はコンパイルエラーになります注1)⁠

if n == 10
    fmt.Println(n)
    // syntax error: missing { after if clause

また,三項演算子はないため次のような書き方はできません。if/else文を使用します。

n == 10 ? fmt.Println(n): fmt.Println(0)
// unexpected name, expecting semicolon or newline or }

Goではこうした多様な書き方を認めないことで,言語の仕様を小さく保つ方針を採っています。

注1)
2014年2月に話題になったAppleのgoto failバグが記憶に新しいでしょう。

for

Goのfor文では,CやJavaでは必要な条件部の丸括弧が必要ありません。

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

Goで繰り返しを表現する方法はfor文以外になく,ほかの言語におけるwhile文やdo/while文,loop文といったような表現は,すべてfor文を用いて行います。

whileもforで

たとえばCのwhile文は,for文で次のように表現します。

// C
int n = 0;
while (n < 10) {
    printf("n = %d\n", n);
    n++;
}

// Go
n := 0
for n < 10 {
    fmt.Printf("n = %d\n", n)
    n++
}

無限ループ

Cの場合,for文を使って次のように無限ループを表現します。

// C
for (;;) {
    doSomething();
}

Goでは,for文の条件部を省略することで同様の表現ができます。

// Go
for {
    doSomething()
}

break,continue

繰り返し制御にはCやJavaと同様に,ループを終了するbreakループの最初から処理を再開するcontinueを使用できます。

func main() {
    n := 0
    for {
        n++
        if n > 10 {
            break // ループを抜ける
        }
        if n%2 == 0 {
            continue // 偶数なら次の繰り返しに移る
        }
        fmt.Println(n) // 奇数のみ表示
    }
}

著者プロフィール

コメント

コメントの記入