0
0
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

Go言語におけるnilの構造体ポインタの扱い方:フィールドとメソッドのアクセス

Posted at

Go言語では、nil の構造体ポインタにアクセスする際には注意が必要です。
特に、フィールドとメソッドにアクセスする場合の動作は異なるため、それぞれのケースについて詳しく解説します。

フィールドにアクセスする場合

nil の構造体ポインタに対してフィールドにアクセスしようとすると、ランタイムパニックが発生します。

package main

import "fmt"

type Foo struct {
	Name string
}

func main() {
	var foo *Foo
	fmt.Println(foo.Name) // panic: runtime error: invalid memory address or nil pointer dereference
}

このコードを実行すると foonil であるため、フィールド Name にアクセスしようとする際にランタイムパニックが発生します。
このような場合、フィールドにアクセスする前にポインタが nil でないことを確認する必要があります。

package main

import "fmt"

type Foo struct {
	Name string
}

func main() {
	var foo *Foo
	if foo != nil {
		fmt.Println(foo.Name)
	} else {
		fmt.Println("foo is nil") // foo is nil
	}
}

メソッドにアクセスする場合

Go言語では、ポインタレシーバを使用したメソッドは nilポインタでも呼び出すことができます。
これは、メソッド呼び出しがレシーバを最初の引数とする関数呼び出しに変換されるためです。

package main

import "fmt"

type Foo struct{}

func (f *Foo) Bar() string {
	return "bar"
}

func main() {
	var foo *Foo
	fmt.Println(foo.Bar()) // bar
}

このコードでは、foonil であっても、メソッド Bar を正常に呼び出すことができます。

エラー処理とnilチェック

レシーバが nil のときに発生する panic は、通常、プログラミングのミスを示すものです。
メソッドの呼び出し前に nil チェックを行い、事前に適切な処理を行う方法が一般的です。

package main

import "fmt"

type Foo struct{}

func (f *Foo) Bar() string {
	return "bar"
}

func main() {
	var foo *Foo
	if foo != nil {
		fmt.Println(foo.Bar())
	} else {
		fmt.Println("foo is nil") // foo is nil
	}
}

ただし、場合によってはメソッド内でnilチェックを行い、処理することもあります。
例えば、レシーバがnilであることを特別なケースとして処理する必要がある場合です。

package main

import "fmt"

type Foo struct{}

func (f *Foo) Bar() string {
	if f == nil {
		return "foo is nil"
	}
	return "bar"
}

func main() {
	var foo *Foo
	fmt.Println(foo.Bar()) // foo is nil
}

まとめ

  • フィールドにアクセスする場合: フィールドにアクセスする前にポインタが nil でないことを確認する必要があります
  • メソッドにアクセスする場合: ポインタレシーバを使用したメソッドは nilポインタでも呼び出すことができますが、メソッド内で nilチェックを行い、適切に処理することが重要です

これらのポイントを理解することで、Go言語における nil の構造体ポインタの扱い方を正しく実装できるようになります。

参考

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