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?

Goのポインタ、オペレータ、オペランド、ポインタレシーバについてChatGPTに聞いたらわかりやすく解説してくれた

Last updated at Posted at 2024-11-22

公式の説明

Pointers

Goはポインタを扱います。 ポインタは値のメモリアドレスを指します。

変数 T のポインタは、 *T 型で、ゼロ値は nil です。

var p *int

& オペレータは、そのオペランド( operand )へのポインタを引き出します。

i := 42
p = &i
  • オペレータは、ポインタの指す先の変数を示します。
fmt.Println(*p) // ポインタpを通してiから値を読みだす
*p = 21         // ポインタpを通してiへ値を代入する

より理解を深めるためにGPT先生に聞いてみたらたとえを出しながら解説してくれたので、以下にその内容を載せます。

ポインタって何?

ポインタは「住所カード」だと思ってください。

例えば:

• ポインタは 「あるデータがどこにあるか」 を指し示すものです。
• もしメモ帳が机の上にあるとしたら、「机の上」という場所をポインタが教えてくれます。
• 実際のメモ帳(中身)はデータそのものです。

Goでは、ポインタは*という記号を使って表現します。

例:ポインタの使い方

package main

import "fmt"

func main() {
    number := 42          // 普通の数値データ
    pointer := &number    // `&`は「住所を教えて!」という意味

    fmt.Println(number)   // 中身を表示:42
    fmt.Println(pointer)  // メモ帳の住所を表示
    fmt.Println(*pointer) // 住所を頼りにメモ帳の中身を読む:42
}

• &number は、numberの住所を取得します。
• *pointer は、住所を使って中身を読むことを意味します。

オペレータとオペランドって何?

これらは数学の用語から来ていますが、プログラムではこんなイメージで考えてください。

• オペレータ:操作をする「道具」や「記号」。
• オペランド:操作される「材料」や「対象」。

例:足し算で考える

式:3 + 5

• + はオペレータ(足し算する道具)
• 3 と 5 はオペランド(計算される材料)

Goのプログラムでも、計算や操作をするときにオペレータとオペランドを使います。

Goでのオペレータの例

Goにはいろいろな種類のオペレータがあります。ポインタと関連するものを挙げます。

1. アドレス取得オペレータ(&)

「このデータの住所を教えて!」という道具。

number := 42
pointer := &number  // numberの住所をpointerに代入
fmt.Println(pointer) // numberの住所が表示される

2. デリファレンスオペレータ(*)

「住所を頼りに中身を見たい!」という道具。

fmt.Println(*pointer) // pointerが指している住所の中身(42)を表示

Goのポインタ、オペレータ、オペランドのまとめ

  1. ポインタ:データの住所カード
  2. &:住所を調べるための道具
  3. *:住所を頼りに中身を覗く道具
  4. オペレータ:操作するための道具
  5. オペランド:操作の対象(データや変数)

Goのポインタは「住所を教えてもらって、中身を操作する仕組み」と理解すればOK!

ポインタを使う理由

ポインタを使うと、データを直接操作したり効率的に処理したりできます。特に以下の場面で便利です

• メモリ節約:大きなデータをコピーする代わりに住所だけを渡す。
• 共有:複数の場所から同じデータを操作できる。

1. 「ポインタレシーバ」って何?

• 「ポインタレシーバ」とは、レシーバ(=メソッドが使う対象)を「住所カード(ポインタ)」で受け取るものです。
• 住所カードを使えば、対象そのものを直接操作できます。住所を使わない場合はコピーを操作するだけになります。

2. 「ポインタレシーバ」を使う理由

• 元のデータ(オリジナル)を変更したいときに使います。
• コピーを操作するのではなく、元データに影響を与えたい場合に便利です。

身近なサンプルコード:銀行口座の例

package main

import "fmt"

// 銀行口座を表す構造体
type BankAccount struct {
	Balance float64 // 口座残高
}

// 1. 残高を表示するメソッド
func (b BankAccount) ShowBalance() {
	fmt.Printf("現在の残高: %.2f円\n", b.Balance)
}

// 2. お金を預け入れるメソッド (ポインタレシーバで定義)
func (b *BankAccount) Deposit(amount float64) {
	b.Balance += amount // 残高を増やす
}

// 3. お金を引き出すメソッド (ポインタレシーバで定義)
func (b *BankAccount) Withdraw(amount float64) {
	if amount > b.Balance {
		fmt.Println("残高不足です。")
		return
	}
	b.Balance -= amount // 残高を減らす
}

func main() {
	// 初期残高 1000円の口座を作成
	myAccount := BankAccount{Balance: 1000}

	// 残高を表示
	myAccount.ShowBalance()

	// 500円を預け入れ
	myAccount.Deposit(500)
	myAccount.ShowBalance()

	// 2000円を引き出そうとする (残高不足)
	myAccount.Withdraw(2000)
	myAccount.ShowBalance()

	// 300円を引き出す
	myAccount.Withdraw(300)
	myAccount.ShowBalance()
}

コードの動き

1. main関数で口座を作成
myAccount := BankAccount{Balance: 1000}

• 残高1000円の口座myAccountを作ります。

2. 残高を表示する(ShowBalance)
myAccount.ShowBalance()

• 「現在の残高: 1000.00円」と表示されます。
• ShowBalanceは残高を変更しないので、変数レシーバ(値レシーバ)で十分です。

3. 500円を預け入れる(Deposit)
myAccount.Deposit(500)

• ポインタレシーバを使うことで、myAccountの残高を直接変更します。
• 残高は 1000 + 500 = 1500円になります。

4. 2000円を引き出す(Withdraw)
myAccount.Withdraw(2000)

• 残高が1500円なので、2000円を引き出そうとするとエラーになります。
• 「残高不足です。」と表示され、残高は変わりません。

5. 300円を引き出す(Withdraw)
myAccount.Withdraw(300)

• 残高は 1500 - 300 = 1200円になります。

ポインタレシーバが重要な理由

• DeDepositやWithdrawでは、残高(Balance)を変更する必要があります。
• ポインタレシーバを使うことで、myAccountそのものを変更できます。
• もし値レシーバにした場合、残高を変更してもコピーにしか影響がなく、元の口座は変わりません。

もしポインタレシーバを使わなかったら?

以下のようにDepositを値レシーバに書き換えると、元のデータは変わらなくなります。

func (b BankAccount) Deposit(amount float64) {
	b.Balance += amount // 残高を増やす
}
実行結果:

現在の残高: 1000.00円
現在の残高: 1000.00円
残高不足です。
現在の残高: 1000.00円
現在の残高: 1000.00円

• 預け入れや引き出しがすべて反映されません。
• コピー(別の口座)が操作されているだけだからです。

ポインタレシーバについてのまとめ

• ポインタレシーバを使うと、元のデータ(口座の残高)を直接操作できます。
• 預け入れや引き出しのようにデータを変更する処理では、ポインタレシーバが必要です。
• 残高を表示するだけの処理では、値レシーバで十分です。

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?