Go(ゴー)言語を学び始めた方が最初にぶつかる壁のひとつが「変数の宣言」です。
シンプルな構文でありながら、用途によって使い分けが必要で、「どの書き方を使えばいいの?」と迷ってしまうことがあります。
本記事では、Go言語での変数の基本的な宣言方法から、ちょっとした応用テクニックまでをわかりやすく解説します。
初心者にもすぐに理解できるよう、具体的な例を交えてご紹介します。
「なぜこんなに書き方があるの?」「どの場面でどの方法を使うべき?」といった疑問にもお答えしながら、実際のプログラミングで役立つ知識を身につけていきましょう。
基本の変数宣言

varキーワードを使った宣言
Go言語では、変数の宣言に「var」キーワードを使います。
これが最も基本的な宣言方法です。
基本的な構文
var 変数名 型名
具体例
var message string
message = "Hello, Go!"
fmt.Println(message) // 出力: Hello, Go!
この例では、文字列型の変数messageを宣言し、後から値を代入しています。
ゼロ値について Go言語では、宣言された変数は自動的に「ゼロ値」で初期化されます。
var number int // 0
var text string // ""(空文字)
var flag bool // false
宣言と同時に初期化
宣言と同時に値を設定することもできます。
var greeting string = "おはよう"
var age int = 25
var isActive bool = true
基本形では「型」を指定するのがポイントです。型を明示することで、コードの意図が明確になり、バグの防止にもつながります。
型推論を使った省略記法
型の自動推論
初期化と同時に宣言する場合、Goコンパイラが値から型を推論してくれるため、型を省略することができます。
var count = 10 // int型として推論
var name = "Gopher" // string型として推論
var price = 99.99 // float64型として推論
短縮宣言演算子(:=)
もっと簡潔に書くには、「:=」を使います。これは「短縮宣言演算子」と呼ばれます。
name := "Gopher"
age := 30
height := 175.5
重要な制限 この「:=」を使う記法は、関数内でのみ使用可能です。パッケージレベル(関数の外)では使えません。
package main
// 関数の外では := は使えない
var globalVar = "グローバル変数"
func main() {
// 関数内では := が使える
localVar := "ローカル変数"
fmt.Println(globalVar, localVar)
}
使い分けのコツ
varを使う場面
- パッケージレベルの変数宣言
- ゼロ値で初期化したい場合
- 型を明示したい場合
:=を使う場面
- 関数内での短い変数宣言
- 型が明らかな場合
- コードを簡潔にしたい場合
型推論はコードを簡潔にする便利な機能です。ただし、可読性を損なわないよう、適切に使い分けることが大切です。
複数変数の同時宣言
基本的な複数宣言
Goでは、一度に複数の変数を宣言・初期化できます。これにより、関連する変数をまとめて管理できます。
同じ型の複数変数
var x, y, z int = 1, 2, 3
fmt.Println(x, y, z) // 出力: 1 2 3
異なる型の複数変数
var name, age, height = "田中", 25, 170.5
// string, int, float64 として推論される
短縮記法での複数宣言
a, b := 5, "Hello"
x, y, z := 10, 20, 30
name, isStudent := "山田", true
ブロック宣言
多くの変数をまとめて宣言する際は、ブロック形式が便利です。
var (
name string = "Go言語"
version int = 1
isStable bool = true
)
実際の使用例
func calculateArea(width, height float64) (float64, float64) {
area := width * height
perimeter := 2 * (width + height)
return area, perimeter
}
func main() {
// 関数の戻り値を複数の変数で受け取る
area, perimeter := calculateArea(5.0, 3.0)
fmt.Printf("面積: %.2f, 周囲: %.2f\n", area, perimeter)
}
複数の変数をまとめて管理できるので、可読性と効率が向上します。関連する値をセットで扱う場合に特に有効です。
使わない変数の処理方法

ブランク識別子(_)の活用
Go言語の特徴として、宣言した変数を使わないとコンパイルエラーになるという厳しいルールがあります。これは未使用変数によるバグを防ぐためですが、時には一部の値だけが必要な場合があります。
問題となるケース
func someFunction() (int, error) {
return 42, nil
}
func main() {
result, err := someFunction()
// errを使わない場合、コンパイルエラーになる
fmt.Println(result)
}
解決方法:ブランク識別子を使用
func main() {
result, _ := someFunction()
// ブランク識別子(_)でエラーを無視
fmt.Println(result)
}
実際の使用例
ファイル操作での例
file, _ := os.Open("example.txt")
// エラーハンドリングを省略する場合(推奨されない)
defer file.Close()
ループでのインデックス無視
fruits := []string{"りんご", "バナナ", "オレンジ"}
for _, fruit := range fruits {
// インデックスは不要、値のみ使用
fmt.Println(fruit)
}
JSON解析での例
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
var person Person
_ = json.Unmarshal(data, &person)
// エラーを無視する場合(本来は適切にハンドリングすべき)
注意点
ブランク識別子は便利ですが、エラーハンドリングを無視するために使うのは推奨されません。特にエラーが重要な意味を持つ場合は、適切に処理しましょう。
// 良い例:エラーを適切にハンドリング
file, err := os.Open("example.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
「_」を使うことで、必要のないデータを無視できます。ただし、重要な情報(特にエラー)を見逃さないよう注意が必要です。
変数のスコープと注意点
スコープの基本
Go言語では、変数のスコープ(有効範囲)を理解することが重要です。
パッケージレベルのスコープ
package main
import "fmt"
var globalVar = "どの関数からでもアクセス可能"
func main() {
fmt.Println(globalVar)
anotherFunction()
}
func anotherFunction() {
fmt.Println(globalVar) // アクセス可能
}
関数レベルのスコープ
func main() {
localVar := "この関数内でのみ有効"
if true {
blockVar := "このブロック内でのみ有効"
fmt.Println(localVar) // アクセス可能
fmt.Println(blockVar) // アクセス可能
}
fmt.Println(localVar) // アクセス可能
// fmt.Println(blockVar) // エラー:スコープ外
}
よくある間違い
同じ名前の変数の再宣言
func main() {
name := "最初の値"
fmt.Println(name)
// 間違い:同じスコープ内での再宣言
// name := "新しい値" // エラー
// 正しい:代入
name = "新しい値"
fmt.Println(name)
}
シャドウイング(変数の隠蔽)
func main() {
x := 10
fmt.Println("外側のx:", x) // 10
if true {
x := 20 // 新しい変数(外側のxを隠す)
fmt.Println("内側のx:", x) // 20
}
fmt.Println("外側のx:", x) // 10(変更されていない)
}
実践的な使用例
構造体での活用
type User struct {
ID int
Name string
Email string
IsActive bool
}
func main() {
// 基本的な宣言
var user1 User
user1.Name = "田中太郎"
user1.Email = "tanaka@example.com"
// 同時初期化
user2 := User{
ID: 1,
Name: "山田花子",
Email: "yamada@example.com",
IsActive: true,
}
// 複数ユーザーの管理
users := []User{user1, user2}
for _, user := range users {
fmt.Printf("ユーザー: %s (%s)\n", user.Name, user.Email)
}
}
エラーハンドリングとの組み合わせ
func processData(filename string) error {
// ファイルを開く
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("ファイルオープンエラー: %w", err)
}
defer file.Close()
// データを読み込む
data, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("ファイル読み込みエラー: %w", err)
}
// データを処理
result := processContent(string(data))
fmt.Println("処理結果:", result)
return nil
}
まとめ:Go言語の変数宣言をマスターしよう
Go言語の変数宣言は、一見シンプルですが実は奥が深い構文です。「var」「:=」「型推論」「複数宣言」「_の活用」などを理解して使いこなすことで、より読みやすく効率的なコードが書けるようになります。
この記事で学んだポイント
- varキーワードによる基本的な変数宣言
- 型推論と短縮宣言演算子(:=)の使い分け
- 複数変数の効率的な宣言方法
- ブランク識別子による不要な値の処理
- 変数のスコープと注意すべき点
使い分けの指針
- 明確性を重視する場合:var文で型を明示
- 簡潔性を重視する場合::=を活用
- 関連する変数をまとめる場合:複数宣言を使用
- 一部の値が不要な場合:ブランク識別子を活用
コメント