はじめに
Go言語を使っていると、よく相手になるのがnil
の存在です。
特に「Goの型はすべてnullable?」と思われがちですが、実際は nilを受け付ける型とそうでない型があります 。
この記事では、Goでnilになりうる型とならない型の違いを明示にし、実用的な解説をします。
nilを受け付ける型(nullable型)
Goで「nullable」という場合、実質的にはnil
を代入可能な型を指します。それらは下記のような型です。
型カテゴリ | 例 |
---|---|
ポインタ型 |
*int , *MyStruct
|
インターフェース |
error , io.Reader
|
スライス | []int |
マップ | map[string]int |
チャネル | chan int |
関数 | func(int) string |
これらはすべてnil
を代入可能で、nil
かどうかをif x == nil
で判断できます。
nilを受け付けない型
一方、以下のような型は「値型」であり、nil
を代入できません。
型カテゴリ | 例 | ゼロ値 |
---|---|---|
基本型 |
int , float64 , bool
|
0 , 0.0 , false
|
配列 | [4]int |
要素すべてゼロ値 |
構造体 | MyStruct |
フィールドすべてゼロ値 |
カスタム値型 | type MyInt int |
0 |
実例:nilになる型とならない型
var a *int // nil
var b int // 0
var c []string // nil
var d [3]string // ["", "", ""]
変数 | 値 |
nil チェック可能か? |
---|---|---|
a | nil | ✅ できる |
b | 0 | ❌ できない (int は nil にならない) |
c | nil | ✅ できる |
d | ["", "", ""] | ❌ できない (array は nil にならない) |
error 型は nullable?
Goでのerror
型はインターフェースであり、nullable (つまり nil
を代入可能)です。なので、以下のような記述もよく見かけます。
func DoSomething() error {
if somethingWentWrong {
return errors.New("oops")
}
return nil // エラーなし
}
nil
は「エラーなし」を意味します。
まとめ
- Goのすべての型がnullableなわけではない
-
nil
を受け付けるのは pointer, interface, slice, map, channel, function - 基本型(int, float, struct, array 等)は nil にならない
-
error
も interface の一種なので nullable