🤢

nilとnullの違いとは??

2023/11/26に公開

nilとは何か?

Golangのnilという値は、いわゆるnull値のことです。nilは、以下のような値を表します。

nilは、値が存在しないことを示す特別な値です。しかし、nullとは異なり、nilは型を持つことができます。例えば、*int32型のnilとinterface{}型のnilは、同じnilでも異なる型を持つため、等しくないと判断されます。これは、Go言語が静的型付け言語であるためです。

例えば、以下のコードでは、*int32型のnilとinterface{}型のnilをキャストしています。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    // var xは、interface{}型の変数
    // interface{}型は、どんな型でも代入できる
    var x interface{} = nil
    // var yは、*int32型の変数
    var y interface{} = (*int32)(nil)
    // isNil関数は、xがnilかどうかを判定する
    fmt.Println(isNil(x)) // true
    fmt.Println(isNil(y)) // true
}

func isNil(x interface{}) bool {
    // reflect.ValueOf(x).IsNil()は、xがnilかどうかを判定する
    return x == nil || reflect.ValueOf(x).IsNil()
}

このコードでは、interface{}型の変数xと*int32型の変数yにnilを代入しています。そして、isNil関数を使って、それぞれの変数がnilかどうかを判定しています。結果として、どちらの変数もnilであると判定されます。しかし、これはGo言語の特性によるもので、他の言語では必ずしも同じ結果にはなりません。

しかし、以下の例では、nilとnilの比較がfalseになる可能性があります。これは、Go言語のnilが型を持つためです。

package main

import (
    "fmt"
)

func main() {
    // var aは、*int32型の変数
    var a *int32 = nil
    // var bは、*int64型の変数
    var b *int64 = nil
    // aとbは、異なる型のnilなので、等しくないと判断される
    fmt.Println(a == b) // false
}

このコードでは、int32型の変数aとint64型の変数bにnilを代入しています。そして、aとbを比較しています。結果として、aとbは等しくないと判定されます。これは、aとbが異なる型のnilであるためです。

そもそもコード実行できないけど...

型が異なる場合

型が同じ場合

まとめ

今回は、nilについて解説しました。nullと違ってcastすることも可能らしく独特だなと考えさせられた。
*ついてるのがありますけど、これはポインター変数であることを意味しています。こちらの記事で解説しております。

https://zenn.dev/joo_hashi/articles/85ad9d10eef979

Jboy王国メディア

Discussion