Goのnilチェックで躓いたのでメモ。
nilチェックは value == nilだとだめな場合がある
こんな挙動になる
type Nameable interface { GetName() string } type Human struct { name string } func (h *Human) GetName() string { return h.name } func IsNilHuman(human Nameable) bool { if human == nil { return true } else { return false } } func main() { if IsNilHuman(nil) { println("nilだ") // こっちにはいる(イメージ通り) } else { println("nilではない") } var nilHuman *Human nilHuman = nil if nilHuman == nil { println("nilだ") // こっちにはいる(イメージ通り) } else { println("nilではない") } if IsNilHuman(nilHuman) { println("nilだ") } else { println("nilではない") // こっちにはいる!(おもてたんとちゃう) } }
なんで?
ここを読んでなんとなく理解した。
絶対ハマる、不思議なnil - Qiita
value == nil
は型も揃っていなければ trueにならない。
意図通りにならなかったパターンでは
[Nameable interface型のnil] == [ただのnil]
という比較になっているのでfalseになる、と理解した。
※[*Humanに代入されたnil] == [ただのnil]
は、代入されたnilは[ただのnil]だから同じ型ということ??ちょっと理解しきれてない。。
確実にチェックするには?
こうするらしい。
func IsNilHuman(human Nameable) bool { if (human == nil) || reflect.ValueOf(human).IsNil() { return true } else { return false } }