Go言語入門:効果的なGo -データ:Maps-

スポンサーリンク
Go言語入門:効果的なGo -データ:Maps- ノウハウ
Go言語入門:効果的なGo -データ:Maps-
この記事は約5分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、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は適切に設定され、oktrueになります。存在しない場合、secondsはゼロに設定され、okfalseになります。以下は、これを適切なエラーレポートとともにまとめた関数です:

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言語におけるマップ(連想配列)の概念と使用方法について詳しく説明しています。

主要なポイント:

  1. マップの基本概念
    • キーと値のペアを関連付けるデータ構造
    • 他の言語では辞書(dictionary)やハッシュテーブルとも呼ばれる
  2. キーの制約
    • 等価演算子(==)が定義されている型のみ使用可能
    • 使用可能:整数、文字列、配列、構造体など
    • 使用不可:スライス(等価性が定義されていないため)
  3. 参照型の特性
    • マップは参照型(スライスと同様)
    • 関数に渡すと、変更が呼び出し元に反映される
  4. 初期化と操作
    • 複合リテラル構文で初期化可能
    • 配列やスライスと似た構文でアクセス
  5. 存在しないキーの処理
    • 存在しないキーはゼロ値を返す
    • これを利用してセット(集合)を実装可能
  6. 「カンマok」イディオム
    • value, ok := map[key]の形式
    • キーの存在を確実に判定する方法
    • Go言語の重要なイディオム
  7. 実用的な機能
    • ブランク識別子(_)で値を無視
    • delete()関数でエントリを削除
    • 存在しないキーの削除も安全
  8. 実際の使用例
    • タイムゾーンの管理
    • セット(集合)の実装
    • 出席者の管理

この知識は、Go言語での効率的なデータ処理において中核となる概念です。特に「カンマok」イディオムは、Go言語プログラミングでは非常に一般的なパターンです。

おわりに 

本日は、Go言語を効果的に使うためのガイドラインについて解説しました。

よっしー
よっしー

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

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました