1. 在庫3から1回売る
  2. 在庫3から3回売ると売切れ
  3. 在庫より多く売ろうとしても壊れない
  4. 1回も売らない
コース一覧
Go入門
ポインタレシーバ

Go入門

変数とゼロ値、Go唯一のループであるfor、複数戻り値とエラー処理、スライスとマップ、構造体とメソッド、ゴルーチンによる並行処理、net/httpによるAPI開発まで、Goの基礎を、毎レッスン実際にコードを書き、フリマアプリのAPIをGoで作りながら学びます。

1
Hello, Go
01. Goとは15分
02. 実行してみる15分
03. packageとmain15分
04. fmtで出力する15分
05. go buildと1バイナリ15分
06. つくる: 起動バナー20分
07. 第1章クイズ10分
2
変数と型
01. varで宣言する15分
02. := の短縮宣言15分
03. ゼロ値(Goならでは)15分
04. 基本の型15分
05. 暗黙変換なし15分
06. 定数とiota15分
07. つくる: 商品データ表示20分
08. 第2章クイズ10分
3
制御構文(forしかない世界)
01. Goのif15分
02. forしかない世界15分
03. forの七変化15分
04. Goのswitch15分
05. 定番: FizzBuzz15分
06. ループで集計15分
07. つくる: 商品集計20分
08. 第3章クイズ10分
4
関数とエラー処理
01. funcで関数を作る15分
02. 複数戻り値(Goならでは)15分
03. if err != nil(Goの心臓)15分
04. エラーを作る15分
05. deferで後始末15分
06. つくる: 検証つき関数群20分
07. 第4章クイズ10分
5
スライスとマップ
01. 配列15分
02. スライス15分
03. appendで育てる15分
04. rangeで走査する15分
05. マップ15分
06. カンマokイディオム15分
07. つくる: 検索と集計20分
08. 第5章クイズ10分
6
構造体とメソッド
01. 構造体15分
02. 初期化とフィールド15分
03. メソッド15分
04. ポインタレシーバ20分
05. New関数の慣習15分
06. 構造体のスライス15分
07. つくる: Itemで再設計20分
08. 第6章クイズ10分
7
ゴルーチンと並行処理のさわり
01. ゴルーチン15分
02. チャネル20分
03. 待ち合わせ20分
04. 並行の落とし穴20分
05. つくる: 並行集計20分
06. 第7章クイズ10分
8
Web API(net/http)
01. サーバーを立てる20分
02. ハンドラ関数20分
03. JSONを返す20分
04. ルーティング20分
05. 一覧API20分
06. 詳細APIと40420分
07. 出品API20分
08. つくる: API主要部完成25分
09. 第8章クイズ10分
9
総合制作
01. 仕様互換を仕上げる25分
02. Node版と差し替える25分
03. 1バイナリでデプロイ25分
04. 自由拡張25分
05. 完成と次のステップ20分

ポインタレシーバ

星印を1つ足す

前のレッスンで、メソッドの中で書き換えても効かない問題がありました。解決策は1文字です。

Go

func (i Item) MarkSoldOut() // 効かない func (i *Item) MarkSoldOut() // 効く

*Item は「Item そのものではなく、Item の居場所」を表します。

Go

func (i *Item) MarkSoldOut() { i.SoldOut = true } item.MarkSoldOut() fmt.Println(item.SoldOut) // true。効いている

なぜ効くのか

値レシーバは、呼ぶたびに中身をコピーして渡します。メソッドの中の i は写しなので、書き換えても元には届きません。

ポインタレシーバは、どこにあるかだけを渡します。メソッドの中の i は元と同じ場所を指しているので、書き換えが元に届きます。

プレーンテキスト

値レシーバ 写しを渡す 書き換えても元は無傷 ポインタレシーバ 場所を渡す 書き換えると元も変わる

第5章の配列とスライスの違いと、同じ構図です。

呼び出し側は同じ

Go

item.MarkSoldOut() // どちらでもこう書く

他の言語なら &item と書く必要がある場面ですが、Go は自動で補います。呼ぶ側からは見分けが付きません。

楽な反面、メソッドの定義を見ないと書き換わるのかどうか分からない、ということでもあります。

どちらを使うか

判断は2つです。

プレーンテキスト

中身を書き換える → ポインタレシーバ 構造体が大きい(コピーが重い) → ポインタレシーバ それ以外 → 値レシーバ

もう1つ、実務で効く決まりがあります。1つの型でレシーバを混ぜないことです。

Go

func (i Item) Label() string // 値 func (i *Item) MarkSoldOut() // ポインタ

動きますが、読む人が毎回どちらか確かめることになります。1つでも書き換えるメソッドがあるなら、その型のメソッドは全部ポインタレシーバに揃えるのが慣習です。

nil に注意

ポインタは「何も指していない」状態になれます。

Go

var i *Item // nil i.MarkSoldOut() // panic: invalid memory address

値レシーバでは起こりえない失敗です。ポインタを使う代償として、nil かどうかを気にする場面が増えます。第8章で JSON を読み込むときに、この形が出てきます。

要件

  1. Sell は在庫を1つ減らす。在庫が0のときは何もしない
  2. 在庫が0になったら SoldOut を true にする
  3. 書き換えが反映されるレシーバを使う
  4. 売切れなら 商品名 売切れ、それ以外は 商品名 在庫N点 を返す

入出力例

sellOut("きのこ図鑑", 3, 1) → "きのこ図鑑 在庫2点" sellOut("きのこ図鑑", 3, 3) → "きのこ図鑑 売切れ" sellOut("古い辞書", 1, 5) → "古い辞書 売切れ" sellOut("中古スマホ", 2, 0) → "中古スマホ 在庫2点"

ヒント

`func (i *Item) Sell()` のように、レシーバの型に `*` を付けます

在庫を減らした後に `if i.Stock == 0 { i.SoldOut = true }` を書きます

在庫より多く売ろうとしても、`if i.Stock > 0` があるのでマイナスにはなりません

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/10

関連レッスン

  • New関数の慣習

    検証つきの生成関数を書き、不正な商品を作れなくできるようになります。

  • 構造体のスライス

    []Itemで一覧を持ち、全データを構造体前提に移行できるようになります。

  • つくる: Itemで再設計

    第6章の知識で検索と集計をItem対応に書き換え、データ層を構造体に統一できます。

  • 第6章クイズ

    構造体、メソッド、ポインタレシーバ、New関数についての理解を確認します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • メソッドクラスに属する関数
  • 配列サイズ固定の同型データの集まり
  • スライス範囲指定で部分列を取り出す記法
  • 判断YES/NO 分岐を表す菱形
  • applicationJSON 本文を送るときの Content-Type
main.go
学習モード
エディタを読み込んでいます

メモ

ポインタレシーバ

⌘S で保存