Skip to main content

Get full access to 実用 Go言語 ―システム開発の現場で知っておきたいアドバイス and 60K+ other titles, with a free 10-day trial of O'Reilly.

There are also live events, courses curated by job role, and more.

3.3 構造体にメソッドを定義する

Goではどのような型に対してもメソッドを追加できます。そのため、構造体も型定義すればメソッドが設定できます。Goはオブジェクト指向言語ではない、とはいうものの、「関数とほぼ同じだがレシーバーを持つ」という特徴は他のオブジェクト指向言語のメソッドとほぼ同一ですし、メソッドを設定された構造体は他のオブジェクト指向言語のクラスにかなり近い存在です。大きなアプリケーションを構成するにあたって、「メソッドを持った構造体」は重要な構成部品となります。本節では、2章のメソッド定義に加えて、構造体を基底型とする型にメソッドを定義するときに課題になることを追加で説明していきます。

メソッドの定義方法は第2章で紹介した通りで、通常のメソッドにレシーバーを(レシーバー変数名 型名)形式で追加したものです。レシーバーの変数名には1文字程度のシンプルな変数名を用いて、selfthisは使わない、と紹介しました。他の言語のメソッドに似ていると紹介しましたが、内部実装も似ていて、レシーバーはゼロ番目の引数として関数に渡されます。

// メソッドを追加する型
// 構造体でなくてもプリミティブ型に対する型も可能
type Struct struct {
	v int
}

// レシーバーを持つ関数としてメソッドを定義
func (s Struct) PrintStatus() {
	log.Println("Struct:", s.v)
}

レシーバーに指定できる型には、値型(Value Receiver)またはポインター型(Pointer Receiver)があります。

3.3.1 値レシーバーとポインターレシーバーのどちらを使えば良いか

レシーバーの型は値型か、ポインター型にします。値型にすると、レシーバーの属性を書き換えても変更は保存されません。ポインターにすれば変更が保存されます。注意点として、値型を指定したレシーバーのフィールド変数を書き換えてもエラーにはなりません。メソッドを呼んでも結果が変更されずおかしい、というバグの原因はたいていこれです。 ...

Get 実用 Go言語 ―システム開発の現場で知っておきたいアドバイス now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.

Don’t leave empty-handed

Get Mark Richards’s Software Architecture Patterns ebook to better understand how to design components—and how they should interact.

It’s yours, free.

Get it now
Cover of Software Architecture Patterns

Check it out now on O’Reilly

Dive in for free with a 10-day trial of the O’Reilly learning platform—then explore all the other resources our members count on to build skills and solve problems every day.

Start your free trial Become a member now