
こんにちは。よっしーです(^^)
本日は、Go言語を効果的に使うためのガイドラインについて解説しています。
背景
Go言語を学び始めて、より良いコードを書きたいと思い、Go言語の公式ドキュメント「Effective Go」を知りました。これは、いわば「Goらしいコードの書き方指南書」になります。単に動くコードではなく、効率的で保守性の高いコードを書くためのベストプラクティスが詰まっているので、これを読んだ時の内容を備忘として残しました。
マップ(Maps)
マップは、ある型の値(キー)を別の型の値(要素または値)に関連付ける便利で強力な組み込みデータ構造です。キーは等価演算子が定義されている任意の型にできます。例えば、整数、浮動小数点数、複素数、文字列、ポインタ、インターフェース(動的型が等価性をサポートしている限り)、構造体、配列などです。スライスは等価性が定義されていないため、マップのキーとして使用できません。スライスと同様に、マップは基盤となるデータ構造への参照を保持します。マップの内容を変更する関数にマップを渡すと、その変更は呼び出し元から見えるようになります。
マップは、コロンで区切られたキー値ペアを持つ通常の複合リテラル構文を使用して構築できるため、初期化時に簡単に構築できます。
var timeZone = map[string]int{
"UTC": 0*60*60,
"EST": -5*60*60,
"CST": -6*60*60,
"MST": -7*60*60,
"PST": -8*60*60,
}
マップの値の割り当てと取得の構文は、配列やスライスの場合とまったく同じに見えますが、インデックスが整数である必要がない点が異なります。
offset := timeZone["EST"]
マップに存在しないキーでマップの値を取得しようとすると、マップ内のエントリの型のゼロ値が返されます。例えば、マップが整数を含んでいる場合、存在しないキーを検索すると0
が返されます。セットは値の型をbool
とするマップとして実装できます。値をセットに入れるにはマップエントリをtrue
に設定し、単純なインデックスでテストします。
attended := map[string]bool{
"Ann": true,
"Joe": true,
...
}
if attended[person] { // personがマップにない場合はfalseになる
fmt.Println(person, "was at the meeting")
}
時には、欠けているエントリをゼロ値と区別する必要があります。"UTC"
のエントリがあるのか、それともマップに全く存在しないから0なのか?多重代入の形式で判別できます。
var seconds int
var ok bool
seconds, ok = timeZone[tz]
明らかな理由で、これは「カンマok」イディオムと呼ばれています。この例では、tz
が存在する場合、seconds
は適切に設定され、ok
はtrue
になります。存在しない場合、seconds
はゼロに設定され、ok
はfalse
になります。以下は、これを適切なエラーレポートとともにまとめた関数です:
func offset(tz string) int {
if seconds, ok := timeZone[tz]; ok {
return seconds
}
log.Println("unknown time zone:", tz)
return 0
}
実際の値を気にせずにマップでの存在をテストするには、値用の通常の変数の代わりにブランク識別子(_
)を使用できます。
_, present := timeZone[tz]
マップエントリを削除するには、マップと削除するキーを引数とするdelete
組み込み関数を使用します。キーがマップに既に存在しない場合でも、これを行うのは安全です。
delete(timeZone, "PDT") // 標準時間になった
解説
この章では、Go言語におけるマップ(連想配列)の概念と使用方法について詳しく説明しています。
主要なポイント:
- マップの基本概念:
- キーと値のペアを関連付けるデータ構造
- 他の言語では辞書(dictionary)やハッシュテーブルとも呼ばれる
- キーの制約:
- 等価演算子(
==
)が定義されている型のみ使用可能 - 使用可能:整数、文字列、配列、構造体など
- 使用不可:スライス(等価性が定義されていないため)
- 等価演算子(
- 参照型の特性:
- マップは参照型(スライスと同様)
- 関数に渡すと、変更が呼び出し元に反映される
- 初期化と操作:
- 複合リテラル構文で初期化可能
- 配列やスライスと似た構文でアクセス
- 存在しないキーの処理:
- 存在しないキーはゼロ値を返す
- これを利用してセット(集合)を実装可能
- 「カンマok」イディオム:
value, ok := map[key]
の形式- キーの存在を確実に判定する方法
- Go言語の重要なイディオム
- 実用的な機能:
- ブランク識別子(
_
)で値を無視 delete()
関数でエントリを削除- 存在しないキーの削除も安全
- ブランク識別子(
- 実際の使用例:
- タイムゾーンの管理
- セット(集合)の実装
- 出席者の管理
この知識は、Go言語での効率的なデータ処理において中核となる概念です。特に「カンマok」イディオムは、Go言語プログラミングでは非常に一般的なパターンです。
おわりに
本日は、Go言語を効果的に使うためのガイドラインについて解説しました。

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント