April 2022
Beginner to intermediate
464 pages
6h 44m
Japanese
Goで構造体を設計するときには「どのように使われるものか」を考える必要があります。ここでは以下の3つの使い方について、構造体を設計する際のポイントを紹介します。
ポインターとして扱うのか? 値として扱うのか? 両方を許可するのか?
値として扱える場合に、イミュータブル(immutable、変更不可能)なオブジェクトとするのか、ミュータブル(mutable、変更可能)なオブジェクトとするのか
値として扱える場合に、ゼロ値での動作を保証するかどうか
最初に決められる方針としては、ポインター型でのみ扱うかどうかです。内部にスライスやmap、ポインターなど参照型の要素を持っている場合には、基本的にポインター型でのみ扱う構造体にします。これらの要素を持っていた場合、構造体をコピーすると、複数のインスタンスが、これらのフィールドのインスタンスを共有することになります。自分だけが参照している要素だと思っていたのに、行った変更が他のインスタンスに影響を与えることになってしまいます。
標準ライブラリでは、ロック状態がコピーされて変なエラーが起きるsync.Mutexや、内部に可変長のバッファを含んだbig.Intなどがこれに該当します。これらの構造体は利用コード内ではポインター型として扱います。sync.Mutexにはありませんが、インスタンスを作成してポインター型を返す、ファクトリー関数を用意すると良いでしょう。
このようなエラーを実行時に防ぐ方法として、作成したときのポインター値を保持しておいてメソッドを呼び出したときにチェックしてエラーを出す方法があります。GoにはC言語などにあるassert ...
Read now
Unlock full access