Go/:=
表示
< Go
Goにおける 区切り子 := は、「短縮変数宣言(short variable declaration)」 を表す演算子で、Go言語の 最も特徴的で便利な機能 の一つです。変数の宣言と初期化を同時に行い、型推論によってコードを簡潔に書くことができます。
- 短縮変数宣言の基本形
// 基本的な短縮変数宣言 x := 42 // var x int = 42 と同等 name := "Go" // var name string = "Go" と同等 pi := 3.14159 // var pi float64 = 3.14159 と同等
:=は 変数の宣言、型推論、初期化 を一度に行います- 右辺の値から自動的に型が決定されます
- 従来の宣言との比較
// 従来の変数宣言 var x int = 42 var name string = "Go" // 短縮変数宣言 x := 42 name := "Go"
- 関数内でのみ使用可能
package main // var globalVar := 42 // エラー: パッケージレベルでは使用不可 var globalVar = 42 // OK: 型推論ありの通常宣言 func main() { localVar := 42 // OK: 関数内では使用可能 }
- 既存変数への代入では使用不可
var x int // x := 42 // エラー: x は既に宣言済み x = 42 // OK: 通常の代入
多重短縮変数宣言
[編集]- 複数変数の同時宣言
// 複数変数の同時宣言と初期化 a, b := 10, 20 name, age := "Alice", 30 x, y, z := 1.0, 2.0, 3.0
- 関数の戻り値との組み合わせ
// 関数の複数戻り値を直接受け取る value, ok := myMap["key"] data, err := os.ReadFile("file.txt") result, success := strconv.Atoi("123")
- 新規変数と既存変数の混在
var err error // 既存変数 // 新規変数 result と既存変数 err の混在 result, err := someFunction() // OK: result は新規宣言、err は代入
- 少なくとも一つの新しい変数 があれば
:=を使用できます
- 少なくとも一つの新しい変数 があれば
- 複雑な混在例
var a, b int var err error // a は既存、c は新規、err は既存 a, c, err := complexFunction() // OK: c が新規変数
型推論の詳細
[編集]- 基本型の推論
i := 42 // int f := 3.14 // float64 s := "hello" // string b := true // bool r := 'A' // rune (int32)
- 複合型の推論
slice := []int{1, 2, 3} // []int m := map[string]int{"a": 1} // map[string]int ch := make(chan int) // chan int fn := func() { fmt.Println("Hi") } // func()
- インターフェース型の推論
var w io.Writer w = os.Stdout // w2 := os.Stdout // *os.File型として推論 // w2 = otherWriter // エラー: 型が固定されている
特殊な使用パターン
[編集]- (1) ブランク識別子との組み合わせ
_, err := os.Open("file.txt") // 戻り値の一部を無視 value, _ := strconv.Atoi("123") // エラーを無視
- (2) 型アサーションでの使用
var i interface{} = 42 value, ok := i.(int) // 型アサーション
- (3) チャンネル操作での使用
ch := make(chan int, 1) ch <- 42 value, ok := <-ch // チャンネルからの受信
- (4) range文での使用
slice := []string{"a", "b", "c"} for i, v := range slice { // インデックスと値を同時に取得 fmt.Printf("%d: %s\n", i, v) }
エラーハンドリングでの活用
[編集]- 典型的なエラーハンドリングパターン
file, err := os.Open("data.txt") if err != nil { return err } defer file.Close() data, err := io.ReadAll(file) if err != nil { return err }
- 連鎖的なエラーハンドリング
func processFile(filename string) error { content, err := os.ReadFile(filename) if err != nil { return err } result, err := processData(content) if err != nil { return err } return saveResult(result) }
他の言語との比較
[編集]- Python
# Python の多重代入 a, b = 1, 2 name, age = "Alice", 30
- JavaScript
// JavaScript の分割代入 const [a, b] = [1, 2]; const {name, age} = {name: "Alice", age: 30};
- C++
// C++17 の構造化束縛 auto [a, b] = std::make_pair(1, 2);
- Go
-
:=は 関数スコープ限定 で型安全- エラーハンドリングのイディオムと密接に結びついている
- シンプルで一貫性のある文法
注意点とベストプラクティス
[編集]- 型の明示が必要な場合
// 明示的な型指定が必要な場合 var timeout time.Duration = 30 * time.Second // timeout := 30 * time.Second // OK: 型推論も可能
- スコープの注意
var err error if condition { result, err := someFunction() // 新しい err がシャドウイング // この err は if ブロック内のみ有効 } // ここでの err は元の変数
- 再宣言の制限
x := 42 // x := 43 // エラー: 同じスコープ内での再宣言は不可 x = 43 // OK: 代入
パフォーマンスへの影響
[編集]- ゼロコスト抽象化
// コンパイル時に最適化される x := 42 // 実行時オーバーヘッドなし y := getValue() // 関数呼び出し自体のコストのみ
- メモリ効率
// 不要な変数宣言を避ける if result, err := expensiveOperation(); err != nil { return err } // result はここでスコープ外
まとめ
[編集]- Goの
:=は 「短縮変数宣言」 を表し、変数の宣言・型推論・初期化を一度に行います - 関数内でのみ使用可能 で、パッケージレベルでは使用できません
- 多重代入 や エラーハンドリング において、Goらしい簡潔で読みやすいコードを書くことができます
- 型推論により、冗長な型宣言を避けながら型安全性を保ちます
- 新規変数と既存変数の混在が可能で、柔軟な変数操作を実現します
「:= は単なる短縮記法ではなく、Goの 『簡潔性と型安全性の両立』 を象徴する、言語設計の核心的な機能です!