0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

7.2.2 nilへの対応についての考察

Posted at

レシーバがnilの場合の対応について以下のように記述がある。

ポインタ型のレシーバは関数の引数にポインタを渡す場合と同じ用に動作します。メソッドに渡されるのはポインタのコピーなのです。関数にnilが渡された場合と同様、コピーのポインタを変更しても、オリジナルは変更されません。つまり、nilを受け取ってnilではないものに変更するようなポインタレシーバは書けません

以下のように書いてみる

func (n *Node) InitIfNil() {
    if n == nil {
        n = &Node{}        // ★ ここでレシーバ変数だけが別の番地を持つ
    }
}
list := (*Node)(nil)
list.InitIfNil()
fmt.Println(list == nil)   // -> true  (呼び出し側は変わらない)

コード中に記載したようにメソッドの呼び出し時にポインタをコピーして実行しているので、メソッドの中でポインタを変更しても呼び出し側には影響がない。

どうしても変更したいような場合には以下のようにポインタのポインタを利用する

func Init(pp **Node) {
    if *pp == nil {
        *pp = &Node{}
    }
}

var list *Node = nil
Init(&list) 

このように元のポインタ変数へのポインタ(**Node)を引数に取れば元のポインタ変数を直接触れるのでnil -> 非nilに変更出来る。

ただし、Go言語においてメソッドのレシーバ型に許されるのは T か *T のみとなるため、メソッドを使う場合この手法は有効でない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?