Go: nil Pointer Receiverの話

Go: nil Pointer Receiverの話

nil Pointer Receiverについてお話しようと思います. 具体例をあげたほうが分かりやすいので, コードを元に説明していきます.

nil Pointer Receiverとは?

下のコードがどのような挙動をするか考えてみてください.

package main

import "fmt"

type A struct {
}

func (a *A) b() {
    fmt.Println(1000)
}

func main() {
    var a *A = nil
    a.b()
}

runtime error: nil Pointer access 的なものが出るだろうと思っていました.

$ go run main.go
1000

サンプル

ちゃんと実行できました. Goでは, nilの場合でもPointer Receiverの場合は実行出来ます. なのでGoでは, Pointer Receiverの中でnilが来ることを考慮しなくてはいけません.

ちなみに, Value Receiverの場合はエラーが出ます.

package main

import "fmt"

type A struct {
}

// b is value Receiver
func (a A) b() {
    fmt.Println(1000)
}

func main() {
    var a *A = nil
    a.b()
}

サンプル

まとめ

nil Pointer Receiverは, デザインパターンの, Null Objectパターンと似ている気がしました. Null Objectパターンでは, 実体のインスタンスをwrapするクラスを作成し, Null Pointer Exceptionを抑制するパターンです. Null Objectパターンを使うことで, クライアント側のコードでNull Checkをする必要がなくなります. Goのnil Pointer Receiverも挙動としては似ていると思いました.

Pointer Receiverを使うときは, 予期せぬ挙動をする可能性があるため, nilの判定をメソッド内で忘れずにして下さい.