Menu
Coddy logo textTech

ポインタレシーバ

CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 8/68。

値レシーバが構造体のコピーを操作するのに対し、ポインタレシーバは元の構造体インスタンスを直接操作します。ポインタレシーバを使用してメソッドを定義すると、そのメソッドはコピーではなく構造体へのポインタを受け取るため、元のデータを変更することができます。

ポインタレシーバを作成するには、レシーバ宣言の型名の前にアスタリスク * を追加します:

type Person struct {
    Name string
    Age  int
}

func (p *Person) haveBirthday() {
    p.Age++  // これは元の構造体を変更します
}

この例では、(p *Person) はポインタレシーバです。Person インスタンスに対して haveBirthday メソッドを呼び出すと、メソッドは元の構造体へのポインタを受け取ります。このポインタを介して構造体のフィールドに加えられた変更は、元のデータを永続的に変更します。

ポインタレシーバは、メソッドが構造体のフィールドを更新する必要がある場合に不可欠であり、データの状態を変更する操作に最適です。

quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

challenge icon

チャレンジ

簡単

このチャレンジでは、シンプルな銀行口座システムを構築することで、ポインタレシーバを持つメソッドの作成を練習します。Account 構造体を作成し、ポインタレシーバを使用して口座残高を変更できるメソッドを定義します。

3つの入力を受け取ります:

  • 口座名義人の名前を表す文字列(例:"John Smith"
  • 初期口座残高を表す文字列(例:"1000.50"
  • 取引金額を表す文字列(例:"250.75"

あなたのタスクは以下の通りです:

  1. 2つのフィールドを持つ Account 構造体を定義します:Name (string) と Balance (float64)
  2. 指定された金額を口座残高に加算する、ポインタレシーバを持つ deposit というメソッドを作成します
  3. 指定された金額を口座残高から減算する、ポインタレシーバを持つ withdraw というメソッドを作成します
  4. 口座情報を "Account: [name], Balance: $[balance]" の形式で出力する、値レシーバを持つ displayBalance というメソッドを作成します
  5. 入力をパースして Account インスタンスを作成します
  6. displayBalance を呼び出して初期残高を表示します
  7. 取引金額を指定して deposit を呼び出します
  8. displayBalance を呼び出して入金後の残高を表示します
  9. 取引金額を指定して withdraw を呼び出します
  10. displayBalance を呼び出して最終的な残高を表示します

残高は小数点以下2桁の精度で表示する必要があります。このチャレンジは、コピーを操作する値レシーバとは異なり、ポインタレシーバによってメソッドが元の構造体データをどのように変更できるかを示しています。

チートシート

ポインタレシーバは、構造体のコピーではなく構造体へのポインタを受け取ることにより、元の構造体インスタンスを直接操作します。これにより、メソッドが元のデータを変更できるようになります。

ポインタレシーバを作成するには、レシーバ宣言の型名の前にアスタリスク * を追加します:

type Person struct {
    Name string
    Age  int
}

func (p *Person) haveBirthday() {
    p.Age++  // これは元の構造体を変更します
}

メソッドが構造体のフィールドを更新する必要がある場合は、ポインタレシーバを使用してください。これにより、データの状態を変更する操作に最適になります。

自分で試してみよう

package main

import (
	"fmt"
	"strconv"
)

// TODO: ここでAccount構造体を定義します

// TODO: ここでポインタレシーバを使用してdepositメソッドを定義します

// TODO: ここでポインタレシーバを使用してwithdrawメソッドを定義します

// TODO: ここで値レシーバを使用してdisplayBalanceメソッドを定義します

func main() {
	// 入力を読み込む
	var name string
	var initialBalanceStr string
	var transactionAmountStr string
	
	fmt.Scanln(&name)
	fmt.Scanln(&initialBalanceStr)
	fmt.Scanln(&transactionAmountStr)
	
	// 文字列の入力を適切な型に変換する
	initialBalance, _ := strconv.ParseFloat(initialBalanceStr, 64)
	transactionAmount, _ := strconv.ParseFloat(transactionAmountStr, 64)
	
	// TODO: Accountインスタンスを作成します
	
	// TODO: 初回残高の表示、入金の実行、残高の表示、出金の実行、最終残高の表示を行います
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

論理とフローのすべてのレッスン