やる気がストロングZERO

やる気のストロングスタイル

【Go】nilチェックは value == nilだとダメな場合がある

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
    }
}