コンテンツにスキップ

Go/Zero value

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go

GoのZero Value(ゼロ値)について

[編集]

Goには、変数を初期化せずに宣言した場合でも自動的に「ゼロ値(zero value)」が代入されるという特徴があります。これは、未初期化変数の安全な使用を保証し、プログラムの簡潔さと堅牢性を高めます。

基本情報

[編集]
  • ゼロ値とは:各型において「何も設定されていない」ことを表すデフォルト値
  • 明示的な初期化を省略してもコンパイルエラーにはならない
  • var で宣言された変数は自動的にその型のゼロ値で初期化される

ゼロ値の具体例

[編集]
ゼロ値 備考
int, int32 0 全ての整数型は 0
float32, float64 0.0 浮動小数点型
complex64, complex128 0 + 0i 複素数型
bool false 真偽値型
string ""(空文字列)
ポインタ型 nil どの型でも *T 型なら nil
スライス、マップ、チャネル、関数、インターフェース nil 使用前に初期化が必要
配列 各要素がゼロ値 [3]int{}[0 0 0]
構造体 各フィールドがゼロ値 struct{X int}{0}

例:変数のゼロ値を確認

[編集]
var i int
var f float64
var s string
var p *int
var b bool

fmt.Println(i) // 0
fmt.Println(f) // 0.0
fmt.Println(s) // ""
fmt.Println(p) // nil
fmt.Println(b) // false

関数パラメータや戻り値との関係

[編集]

Goでは戻り値の省略も可能なため、関数がエラー発生時にゼロ値を返すケースが多くあります。

func findUser(id int) (name string, exist bool) {
    if id == 0 {
        return // name="", exist=false : ゼロ値で返す
    }
    name, exist = "Alice", true
    return 
}

スライスやマップのゼロ値と初期化の違い

[編集]
var m map[string]int // ゼロ値:nil
m["key"] = 1         // panic: assignment to entry in nil map

// 初期化が必要
m = make(map[string]int)
m["key"] = 1         // OK
var s []int          // ゼロ値:nil
fmt.Println(len(s))  // 0(ただし append は使える)
s = append(s, 1)     // OK

ユースケース

[編集]
  1. 明示的に初期化する必要がない
    var buf [1024]byte // 全要素が 0 で初期化済み
    
  2. ゼロ値を意味として使う
    type Config struct {
        Port int    // 0 を指定したらデフォルトポートに切り替えるなど
        Host string // "" なら localhost
    }
    
  3. エラー時にゼロ値を返すAPI設計
    func GetItem(index int) (item string, ok bool) {
        if index < 0 {
            return "", false
        }
        return "apple", true
    }
    

ゼロ値はGoの安全で簡潔なプログラミングスタイルを支える基盤のひとつです。未初期化変数でも安全に使用できる設計により、プログラムの堅牢性が高まります。特に構造体やスライス、マップなどの複合型ではゼロ値と初期化済みの違いを理解し、必要に応じて makenew による明示的な初期化を使い分けることが重要です。