0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go言語における `[]` と `{}` の使い分け

Posted at

Go言語のソースコードを見たとき、[]{} の使い分けに戸惑ったことはありません?わたしは、めっちゃアリます!他の言語とスイッチする時に混乱しやすいため、備忘録としてまとめました。 

角括弧 [] の役割と具体例

1. コレクション型の定義

// 配列(固定長): [要素数]型
var array [3]int  // [0, 0, 0]

// スライス(可変長): []型
var slice []string // nilスライス

// マップのキー型指定: map[キー型]値型
var m map[string]int // nilマップ

2. 要素アクセスとスライス操作

arr := [5]int{10, 20, 30, 40, 50}

// 要素アクセス
fmt.Println(arr[2]) // 30

// スライス操作(半開区間)
slice := arr[1:4] // [20, 30, 40]

// 容量と長さの取得
fmt.Println(len(slice), cap(slice)) // 3, 4

3. バッファ付きチャネル

ch := make(chan int, 10) // バッファサイズ10

波括弧 {} の役割と具体例

1. 複合リテラル(初期化)

// スライス初期化
names := []string{"Alice", "Bob", "Charlie"}

// マップ初期化
scores := map[string]int{
    "Math":    90,
    "Science": 85, // 末尾カンマ必須
}

// 構造体初期化
type User struct {
    ID   int
    Name string
}
user := User{ID: 1, Name: "Alice"}

2. ブロック定義

// if文の条件ブロック
if count > 5 {
    fmt.Println("Threshold exceeded")
}

// 関数本体
func calculate(a, b int) int {
    return a * b
}

// 無名関数
func() {
    fmt.Println("Immediate execution")
}()

[]{} の組み合わせパターン

スライスの宣言と初期化

// 型推論を利用
fibonacci := []int{0, 1, 1, 2, 3, 5}

// 多次元スライス
matrix := [][]int{
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
}

マップの動的初期化

// マップの宣言と初期化
config := map[string]string{
    "env":  "production",
    "port": "8080",
}

// 後から要素追加
config["timeout"] = "30s"

構造体スライスの初期化

type Point struct{ X, Y int }

// 複合リテラルで一括初期化
points := []Point{
    {X: 1, Y: 2},
    {X: 3, Y: 4},
    {X: 5, Y: 6},
}

実践的ユースケース

ケース1: JSONデータの処理

import "encoding/json"

type Product struct {
    ID    int      `json:"id"`
    Name  string   `json:"name"`
    Tags  []string `json:"tags"`
}

// JSON → Go構造体
jsonData := []byte(`{"id":101,"name":"Laptop","tags":["tech","electronics"]}`)

var p Product
json.Unmarshal(jsonData, &p)

fmt.Println(p.Tags[1]) // "electronics"

ケース2: エラーハンドリング

if err := process(); err != nil {
    // エラー型による分岐
    switch e := err.(type) {
    case *NetworkError:
        log.Printf("Network error: %v", e)
    case *ValidationError:
        log.Printf("Validation failed: %v", e)
    default:
        log.Printf("Unexpected error: %v", err)
    }
}

ケース3: 並行処理でのマップ使用

var (
    mu    sync.Mutex
    cache = make(map[string]time.Time)
)

func updateCache(key string) {
    mu.Lock()
    defer mu.Unlock()
    cache[key] = time.Now() // 排他制御下でのマップ更新
}

他言語との比較表

機能 Go言語 Python JavaScript/TypeScript
配列/リスト [n]T, []T list = [1,2,3] const arr: number[]
マップ/辞書 map[K]V{} dict = {"key":value} const obj: Record<K,V>
構造体/クラス struct{...}{} クラス__init__ インターフェース/クラス
ブロック { ... } インデント { ... }
スライス操作 slice[1:4] list[1:4] arr.slice(1,4)

よくある間違いと解決策

エラー1: マップ初期化の構文ミス

// 誤り: マップに[]を使用
m := map[string]int["a":1, "b":2] 

// 正しい方法
m := map[string]int{"a":1, "b":2}

エラー2: 構造体初期化の型不一致

type Config struct {
    Timeout int
}

// 誤り: 文字列をintフィールドに代入
c := Config{Timeout: "30"} 

// 正しい方法
c := Config{Timeout: 30}

エラー3: スライスの範囲外アクセス

s := []int{10, 20, 30}

// パニック発生
fmt.Println(s[5]) 

// 安全なアクセス方法
if len(s) > 5 {
    fmt.Println(s[5])
}

ベストプラクティス

  1. 複合リテラルのフォーマット規則

    // 複数行の場合
    profile := map[string]string{
        "name":    "Alice",
        "email":   "alice@example.com",
        "country": "JP", // 末尾カンマ必須
    }
    
  2. makeを使ったスライス初期化

    // キャパシティ指定でメモリ割当最適化
    ids := make([]int, 0, 100) // 長さ0, 容量100
    
  3. マップの存在チェック

    if value, exists := configMap["timeout"]; exists {
        // キーが存在する場合の処理
    }
    
  4. 構造体初期化時のフィールド明示

    // フィールド名明示(順番変更に強い)
    u := User{
        ID:   101,
        Name: "Bob",
    }
    

Go言語の設計思想から見る括弧の意味

Go言語の括弧の使い分けには、言語設計の核となる原則が反映されています:

  • 明示性: [] は型定義、{} は初期化とブロック
  • 簡潔性: 複合リテラル構文による直感的な初期化
  • 型安全性: コンパイル時の厳密なチェック
  • 実用性: スライス操作など日常的な操作の最適化

「Goの構文は小さな言語を意図して設計されている。すべての構文要素は明確な目的を持ち、一貫した方法で動作する」
- Go言語設計者 Rob Pike

まとめ

Go言語の []{} の使い分けをマスターすることは、Goのコアコンセプトを理解する上で不可欠です:

  1. []型定義・要素アクセス・スライス操作 に使用
  2. {}初期化・ブロック定義 に使用
  3. 組み合わせて 複合データ構造 を効率的に操作
  4. 他言語との違いを理解して マイグレーション時に混乱を回避
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?