Go言語(Golang)を学び始めると、変数の宣言方法に2つの主要な形式があることに気づきます。

一つはキーワード var を使用する方法で、もう一つは短縮変数宣言と呼ばれる := を使用する方法です。

プログラミング初心者だけでなく、他の言語から移行してきたエンジニアにとっても、この2つの使い分けはしばしば混乱の種になります。

「どちらを使っても動くなら、短くて便利な := だけで良いのではないか」と考える方も少なくありません。

しかし、Go言語の設計思想において、これらには明確な役割の違いと適切な使用シーンが定義されています。

本記事では、2026年現在のモダンな開発スタイルを踏まえ、 var:= の仕様上の違いから、実務で推奨される使い分けのルールまでを詳しく解説します。

Goにおける変数宣言の基本

まずは、それぞれの宣言方法がどのような構文を持ち、どのような挙動をするのかを整理しましょう。

var による宣言

var は、Go言語において最も基本的かつ明示的な変数宣言の方法です。

この形式では、変数名、型、そして必要に応じて初期値を指定することができます。

Go
package main

import "fmt"

func main() {
    // 型を明示して宣言(初期値なし)
    var message string
    message = "Hello, Go!"

    // 型を明示して宣言(初期値あり)
    var count int = 10

    // 型推論を利用した宣言
    var isActive = true

    fmt.Println(message, count, isActive)
}
実行結果
Hello, Go! 10 true

var を使った宣言の大きな特徴は、変数の「型」をプログラマが明示的にコントロールできる点にあります。

また、初期値を与えずに宣言した場合は、その型の「ゼロ値」で初期化されるという性質を持っています。

:= による短縮変数宣言

一方、 := は「短縮変数宣言」と呼ばれ、 var キーワードと型指定を省略して記述できる便利な構文です。

この構文は、右辺の型から左辺の変数の型を自動的に決定する「型推論」を前提としています。

Go
package main

import "fmt"

func main() {
    // 短縮変数宣言
    name := "Gopher"
    age := 15

    fmt.Printf("Name: %s, Age: %d\n", name, age)
}
実行結果
Name: Gopher, Age: 15

短縮変数宣言は、コードを簡潔に保つために非常に有効であり、Go言語の関数内では最も一般的に利用される宣言方法です。

しかし、便利な反面、使用できる場所に制限があるなど、いくつかの制約が存在します。

var と := の決定的な違い

これら2つの宣言方法には、単なる記述の長さ以外に4つの大きな違いがあります。

1. 宣言可能な場所(スコープ)の違い

最も重要な違いは、その変数をどこで宣言できるかという点です。

var は、関数の外(パッケージレベル)と関数の内の両方で使用することが可能です。

対して、 短縮変数宣言(:=)は関数の中でしか使用できません。

Go
package main

// パッケージレベルでの宣言(OK)
var globalVar = "I am global"

// パッケージレベルでの短縮宣言(NG: コンパイルエラー)
// shortVar := "I will fail"

func main() {
    // 関数内であればどちらも可能
    var localVar = "I am local"
    shortVar := "I am also local"
}

パッケージ全体で共有するグローバル変数や、定数に近い扱いをする変数を定義する場合は、必ず var を使用する必要があります。

2. ゼロ値の利用可否

Go言語では、変数に初期値を与えない場合、その型のデフォルト値である「ゼロ値」が割り当てられます。

var は初期値を省略できるため、ゼロ値での初期化を意図する場合に最適です。

しかし、 := は右辺の値を参照して型を決める仕組みであるため、必ず初期値を指定しなければなりません。

Go
var i int        // i は 0 で初期化される
var s string     // s は ""(空文字)で初期化される
var slice []int  // slice は nil で初期化される

後から値を代入するために変数だけを先に用意しておきたいシーンでは、 var が必須となります。

3. 型の明示的な指定

:= は常に右辺の型を採用します。

例えば、数値の 10 を代入すると、型推論によってデフォルトの int 型になります。

もし特定のサイズ(int64float32 など)を指定したい場合、 := ではキャスト(型変換)が必要になります。

Go
// var を使った場合
var price int64 = 1500

// := を使った場合(明示的な変換が必要)
amount := int64(2000)

このように、特定の型であることを強調したい、あるいは推論される型とは異なる型を適用したい場合は var を使う方がコードの意図が伝わりやすくなります。

4. 再宣言の挙動

同じスコープ内で var を使って同じ変数名を二度宣言することはできません。

しかし、 := には特別なルールがあり、「複数の変数を同時に宣言・代入する場合、少なくとも1つが新しい変数であれば既存の変数の再利用が許される」という性質があります。

これは、エラーハンドリングなどの処理で頻繁に利用されます。

Go
func main() {
    f, err := os.Open("file1.txt")
    if err != nil {
        return
    }
    
    // err は既に宣言済みだが、f2 が新規変数なので := が使える
    f2, err := os.Open("file2.txt")
    if err != nil {
        return
    }
}

比較表:var と := の特徴まとめ

ここまでの違いを、一目でわかるように表にまとめました。

特徴var:=
使用可能な場所どこでも(関数外/内)関数内のみ
型の指定明示・推論の両方可能型推論のみ
初期値の省略可能(ゼロ値になる)不可
主な用途グローバル、ゼロ値初期化ローカル変数の即時利用

実務における最適な使い分けガイド

Go言語のコミュニティや公式ドキュメント(Effective Goなど)が推奨する、実践的な使い分けのベストプラクティスを紹介します。

原則として関数内では := を選ぶ

ローカル変数において、初期値が明確である場合は := を使用するのが標準的です。

これにより、冗長な var キーワードを排除し、コードの可読性を高めることができます。

特に、関数の戻り値を直接受け取る場合は、ほぼ 100% のケースで := が選択されます。

意図的に var を選ぶべきシーン

以下のようなケースでは、 := ではなく var を積極的に使用します。

1. ゼロ値を利用する場合

変数を宣言した時点では具体的な値が決まっておらず、後で代入や追加を行う場合は var を使います。

Go
// スライスを用意して、後から append する場合
var names []string
names = append(names, "Alice")

これを names := []string{} と書くこともできますが、 var を使う方が「空の状態から始める」という意図が明確になります。

2. 型を厳密に制御したい場合

Goの型推論は強力ですが、インターフェース型として変数を保持したい場合など、推論に任せたくないことがあります。

Go
// Buffer型ではなく、io.Writerインターフェースとして扱いたい場合
var w io.Writer = new(bytes.Buffer)

このように宣言することで、変数 wio.Writer に準拠していることをコンパイル時に保証し、設計の意図を明示できます。

3. パッケージレベルの変数

先述の通り、関数の外では var しか使えません。

設定値や、複数の関数から参照される共有リソースを定義する際は、迷わず var を選択しましょう。

注意点:変数のシャドウイング(Shadowing)

:= を多用する際に最も注意すべきなのが「変数のシャドウイング」です。

これは、外側のスコープで定義された変数と同じ名前を、内側のスコープで := を使って宣言してしまうことで発生します。

Go
func main() {
    x := 10
    if x > 5 {
        // 外側の x を更新するのではなく、新しい x を宣言してしまう
        x := 20 
        fmt.Println("Inner:", x)
    }
    fmt.Println("Outer:", x)
}
実行結果
Inner: 20
Outer: 10

このミスはバグの原因になりやすいため、既存の変数に新しい値を代入したいだけのときは =(単純代入演算子)を使うよう徹底してください。

まとめ

Go言語における var:= の違いを理解することは、クリーンでメンテナンスしやすいコードを書くための第一歩です。

:= は関数内での記述を簡潔にし、開発スピードを向上させてくれます。

一方で var は、型の明示やゼロ値の活用、パッケージレベルでの宣言といった、プログラムの構造を決定づける重要な場面で力を発揮します。

「基本は := を使い、必要性があるときだけ var を選ぶ」という方針を持っておけば、迷うことは少なくなります。

それぞれの特性を正しく把握し、状況に応じた最適な宣言方法を選択できるようになりましょう。

こうした細かな使い分けの積み重ねが、Goらしいシンプルで読みやすいコードを作り上げます。