ProgrammingGoバックエンド開発者

Goにおける変数の初期化はどのように行われ、ゼロ値を使用することの危険性は何ですか?

Hintsage AIアシスタントで面接を突破

回答

Goでは、明示的な初期化子なしに宣言された変数は、自動的にいわゆる_ゼロ値_(zero values)を取得します。これは異なるタイプによって異なります:

  • int — 0
  • bool — false
  • string — ""
  • ポインタ、インターフェース、スライス、マップ、チャネル、関数 — nil

これは便利ですが(メモリ内のゴミがないため)、危険な場合があります。たとえば、スライスやマップのような一部のタイプでは、nil値を扱うことがパニックやバグにつながる可能性があります。

例:

var m map[string]int m["key"] = 1 // panic: nilマップへのエントリの割り当て var s []int fmt.Println(s, s == nil) // [] true (要素を追加できますが、インデックスでアクセスすることはできません)

ひっかけの質問

nilスライスのnil値とnilマップ/チャネルのnil値の違いは何ですか?また、それはどのようなバグを引き起こしますか?

正しい答え:nil値のスライスは関数に渡したり、appendやrangeで使用することができます。これは安全ですが、nilマップでの作業は書き込みを試みるとパニックを引き起こします(ただし、読み取りは許可されておりゼロ値を返します)。

例:

var m map[string]int fmt.Println(m["no_key"]) // 0 — 安全 m["key"] = 1 // panic! var s []int s = append(s, 42) // ok

このトピックの微妙な点を知らないことによる実際のエラーの例


物語

説明: 大規模なプロジェクトで、データ集約に未初期化のマップを使用しました。最初の書き込み時にアプリケーションが安定してpanicで落ちました。問題は、新しい統計を導入したときにプロダクションで発見されました。


物語

説明: サービスは未初期化のスライスをシリアライズし、API応答としてJSONで送信しました。クライアントは[]の代わりにnullを受け取り、両方のバリエーションを処理するためにフロントエンドのスキーマを変更する必要がありました。


物語

説明: キャッシュモジュールでnilマップと空のマップを不適切に比較し、その結果、要素が存在するかどうかを正しく判断できませんでした。これによりデータベースへの余分な呼び出しが発生し、パフォーマンスが低下しました。