Skip to content

データ構造

Go 言語は構文が簡潔ですが、強力なコアデータ構造が多数組み込まれています。これらのデータ構造は Go プログラムの基本的な構築ブロックであり、その実装原理を深く理解することで、より効率的なコードを書くことができます。本記事では Go で最も一般的に使用されるいくつかのデータ構造とその底层実装について紹介します。

基本データ構造

slice スライス

スライスは Go 言語で最も一般的に使用されるデータ構造で、配列の抽象化とカプセル化です。主な特徴:

  • 動的サイズ:スライスの長さは動的に拡張可能
  • 参照セマンティクス:スライスは渡す際に構造体のみコピーされ、底层配列はコピーされない
  • 拡張メカニズム:容量が不足すると自動的に拡張される

スライスは実行時に slice 構造体で表され、底层配列へのポインタ、長さ、容量の 3 つのフィールドを含む。

string 文字列

文字列は Go の最も基本的なデータ型の一つで、主な特徴:

  • 不変性:文字列は作成後は変更できない
  • UTF-8 エンコーディング:通常 UTF-8 エンコードされたテキストを表す
  • ゼロ値安全:文字列のゼロ値は空文字列 "" で、nil ではない

文字列は実行時に stringStruct 構造体で表され、バイト配列へのポインタと長さを含む。

コンテナデータ構造

map マップ

map は Go 言語に組み込まれたキーバリューコンテナで、ハッシュテーブルとして実装されています。主な特徴:

  • ハッシュテーブル実装:ハッシュ関数で要素を素早く特定
  • 自動拡張:負荷因子が高くなると自動的に拡張
  • 非同期安全:同時読み書きには追加の同期機構が必要

map は実行時に hmap 構造体で表され、バケット配列、ハッシュシード、要素カウントなどのフィールドを含む。

syncmap 並行マップ

sync.Map は標準ライブラリが提供する並行安全なマップで、読みが多く書きが少ないシーンに適しています。主な特徴:

  • 読み書き分離:read と dirty の 2 つの map で読み書きを実現
  • アトミック操作:read map はアトミック操作を使用し、ロック不要
  • 段階的移行:miss カウントが閾値に達すると dirty を read に昇格

sync.Map は空間を時間で置き換える方式により、特定のシーンで map + mutex よりも優れたパフォーマンスを提供します。

並行データ構造

channel チャネル

channel は Go 言語の CSP 思想を体現する代表的なもので、ゴルーチン間の通信に使用されます。主な特徴:

  • ゴルーチン通信:channel を通じてゴルーチン間のデータ転送を実現
  • 同期機構:バッファなし channel はゴルーチン同期に使用可能
  • ロック付きキュー:底层はロック付きの環状キュー

channel は実行時に hchan 構造体で表され、環状バッファ、待機キューなどのフィールドを含む。

select 多重化

select は複数の channel の状態を同時に監視し、多重化を実現します。主な特徴:

  • ノンブロッキング:複数の channel の可用性をノンブロッキングでチェック
  • ランダム選択:複数の channel が同時に使用可能な場合、ランダムに 1 つを選択して実行
  • タイムアウト制御time.After と組み合わせてタイムアウト機構を実装

select は実行時に scase 構造体で各ブランチを表し、ポーリング機構で channel の状態をチェックします。

学習のアドバイス

以下の順序で学習することをお勧めします:

  1. まず slice スライスstring 文字列 を学び、基本データ構造を理解
  2. 次に map マップ を学び、ハッシュテーブルの実装を理解
  3. その後 channel チャネル を学び、ゴルーチン通信機構を理解
  4. 次に select 多重化 を学び、多重化テクニックを習得
  5. 最後に syncmap 並行マップ を学び、並行安全の実装方法を理解

Golang学习网由www.golangdev.cn整理维护