3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Go言語のポインタレシーバと値レシーバの使い分け

Posted at

はじめに

Go言語では、メソッドの実装時にポインタレシーバと値レシーバのどちらを使うかが重要な選択となります。
この記事では、それぞれの使い分けについて確認していきたいと思います。

ポインタレシーバについて

ポインタレシーバは、メソッドが呼び出される際に、構造体のアドレス(参照)が渡されます。これにより、メソッド内で構造体のデータを直接変更することができます。また、メソッドの呼び出しに伴って構造体がコピーされないため、メモリ使用量が削減されることがあります。

メリット

  1. メモリ使用量が削減される: ポインタレシーバを使用すると、構造体がコピーされないため、パフォーマンスが向上し、メモリ使用量が削減されます。
  2. 構造体のデータを変更できる: ポインタレシーバを使用すると、構造体のデータを直接変更できます。これにより、副作用を持つメソッドを実装することができます。

デメリット

  1. 構造体の内容が変更される: ポインタレシーバを使用すると、メソッド内で構造体の内容を変更すると、オリジナルのデータも変更されます。これは、構造体のコピーが行われないためです。

コードでの確認

以下の例では、銀行口座を表すAccount構造体があり、Depositメソッドを実装しています。
このメソッドは、ポインタレシーバを使用しています。

package main

import "fmt"

type Account struct {
	owner   string
	balance float64
}

// ポインタレシーバを使ったDepositメソッド
func (a *Account) Deposit(amount float64) {
	a.balance += amount
}

func main() {
	account := Account{owner: "Goher", balance: 1000.0}

	// ポインタレシーバを使った場合
	account.Deposit(500)
	fmt.Printf("After deposit with pointer receiver: %v\n", account) // {Goher, 1500.00}
}

この例で、Depositメソッドを使って口座に500ドルを預けた後、残高が正しく更新されています。
ポインタレシーバを使っているため、オリジナルの構造体のデータが直接変更されています。

まとめ

ポインタレシーバは、メモリ効率を向上させるためや、構造体のデータを変更するメソッドを実装する際に有用です。ただし、オリジナルのデータも変更されるため、その点に注意が必要です。一般的に、以下のケースでポインタレシーバを使用することが推奨されます。

  1. 構造体が大きく、コピーによるパフォーマンスの低下が懸念される場合
  2. メソッド内で構造体のデータを変更する必要がある場合

これらのポイントを考慮して、ポインタレシーバを適切に使用することで、効率的かつ安全なアプリケーションの実装が可能になります。

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?