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.6 構造体を設計するポイント

Goで構造体を設計するときには「どのように使われるものか」を考える必要があります。ここでは以下の3つの使い方について、構造体を設計する際のポイントを紹介します。

  • ポインターとして扱うのか? 値として扱うのか? 両方を許可するのか?

  • 値として扱える場合に、イミュータブル(immutable、変更不可能)なオブジェクトとするのか、ミュータブル(mutable、変更可能)なオブジェクトとするのか

  • 値として扱える場合に、ゼロ値での動作を保証するかどうか

3.6.1 ポインター型として扱う必要があるケース

最初に決められる方針としては、ポインター型でのみ扱うかどうかです。内部にスライスやmap、ポインターなど参照型の要素を持っている場合には、基本的にポインター型でのみ扱う構造体にします。これらの要素を持っていた場合、構造体をコピーすると、複数のインスタンスが、これらのフィールドのインスタンスを共有することになります。自分だけが参照している要素だと思っていたのに、行った変更が他のインスタンスに影響を与えることになってしまいます。

標準ライブラリでは、ロック状態がコピーされて変なエラーが起きるsync.Mutexや、内部に可変長のバッファを含んだbig.Intなどがこれに該当します。これらの構造体は利用コード内ではポインター型として扱います。sync.Mutexにはありませんが、インスタンスを作成してポインター型を返す、ファクトリー関数を用意すると良いでしょう。

このようなエラーを実行時に防ぐ方法として、作成したときのポインター値を保持しておいてメソッドを呼び出したときにチェックしてエラーを出す方法があります。GoにはC言語などにあるassert ...

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