nilとは何か interfaceの構造とnil-not-equal-nilから理解する¶
チェック¶
- [ ] 本文を確認した
- [ ] 概要を確認した
- [ ] タグを確認した
- [ ]
inbox/直下へ移行した
概要¶
Go の nil を言語仕様と interface 内部構造から理解する資料。
nil は keyword ではなく predeclared identifier であり、default type を持たない。
interface は型情報と値を持つため、typed nil が入ると値が nil でも interface 全体は nil ではない、という nil != nil 問題が起きる。
実務での付き合い方も扱う構成。
本文¶
資料の流れは次の通り。
nilを言語仕様から見る- interface の内部構造と
nil != nil - 改善提案の歴史
- 実務での付き合い方
nil は Go の keyword ではない。
if、func、return、go などは keyword であり変数名に使えないが、nil は true、false、iota と同じ predeclared identifier。
そのため shadowing できる。
また、predeclared identifier の中で default type を持たないのは nil だけ。
true は bool、iota は int として扱われるが、nil 単体では型が決まらない。
Go の interface は、内部的に型情報と値を持つ。
したがって、var p *T = nil を interface に代入すると、値 pointer は nil でも *T という型情報が入る。
この状態の interface は nil ではない。
この問題は、error interface を返す関数で typed nil を返してしまうと実務上の bug になる。
interface を返す関数では、nil pointer をそのまま interface に詰めず、nil の場合は明示的に return nil する必要がある。
要点¶
nilは keyword ではなく predeclared identifier。nilは default type を持たない。- interface は型情報と値を持つため typed nil が問題になる。
errorを返す関数では typed nil を返さないよう注意する。nil比較は runtime 表現を理解して読む必要がある。