Golang プロポーザル:container/ パッケージでのジェネリックコレクション型

2026/08/01 3:39

Golang プロポーザル:container/ パッケージでのジェネリックコレクション型

RSS: https://news.ycombinator.com/rss

要約

Japanese 翻訳:

次の改善版では、特定のデータ構造を統合し、Go 1.28 とそれ以前のリリース間の範囲を明確にし、主要な要点からアーキテクチャの詳細を取り入れています。

サマリー:

Go 1.28 は、新しい Go Collections API のための主要な汎用リリースとして機能し、言語の歴史的な順序付きマップおよびセットの欠如に対応しています。このイニシアチブは、

container/ordered.Map
(挿入順序による格納を実現するために平衡二分木を実装)、
container/set.Set
(Union および Intersection などの正規操作をサポート)、そしてカスタムハッシュ関数を利用する
container/hash.Map/Set
を含む複数の重要な提案を統合します。このリリースでは、標準のヒープ実装を置き換えるための
container/heap/v2
も導入され、
container/mapset
のようなレガシーヘルパーも提供されています。

API デザインは、特定のアーキテクチャ選択を通じて安全性と効率性を最優先しています:二分木のパフォーマンスを維持するため

DeleteFunc
を維持しつつ、Set インターフェースから
Subset
を除外して過度な負担を避けるという方針を取っています。特徴的なのは、異なるセット型の互換性のない Union メソッドが共通の通常のインターフェースを共有しないように(「バイナリメソッド問題」を解決)、安全に二分探索メソッドを取り扱うために F 限界多型を採用している点です。挿入順序付きハッシュマップなどのいくつかの提案は将来のリリースのために検討中である一方で、このツールのコレクションはデータ構造の標準化を行い、エコシステムの分断を軽減すると同時に、Go の厳格な後方互換性を損なうことなく深い比較機能を 제공합니다。

本文

Go Collections: 標準ライブラリへの新たなコレクション API

背景と目的

Go Collections ワーキンググループは、2025 年末に設立されました。

  • 設立趣旨: Go の「実践主義」と「簡潔性」の原則に基づき、共通のコレクションデータ構造を標準ライブラリに取り入れることを目的としています。
  • 主要メンバー:
    • Jonathan Amsterdam (@jba)
    • Alan Donovan (@adonovan)
    • Robert Griesemer (@griesemer)
    • Daniel Martí (@mvdan)
    • Roger Peppe (@rogpeppe)
    • Keith Randall (@khr)
    • Ian Lance Taylor (@ianlancetaylor)
  • 現状の課題:
    • 標準ライブラリにはスライスとマップしか提供されておらず、ヒープ以外の実装は限られています。
    • 集合
      は完全に欠けており、慣習として
      map[T]bool
      または
      map[T]struct{}
      が使用されています。
    • 順序付けされたマップやセットも存在しません。
  • ジェネリックとイテレータの進展:
    • Go 1.18 でジェネリック、Go 1.23 でイテレータ機能が追加され、ライブラリ型でも組み込み型に近い使いやすさが実現可能になりました。
    • 本作業は標準ライブラリに重要なデータ構造を追加し、API の慣習を設定することを目的としています。

提案される新しい API

以下のように、複数の新しい型やパッケージが追加予定されています。

Issue #CL 番号パッケージ/型名概要
#70471CL 657296
hash/maphash.Hasher
go1.27 リリース済み。カスタムハッシュ関数および等価性のインターフェースを提供します。
map[K]V
のコンパイル時定義とは異なり、キー型が比較できない場合や深い比較が必要になる場合に有用です。
#69559CL 612217
container/hash.Map[K,V]
カスタムハッシュ関数を使用したハッシュベースのマップ型。
#80584CL 741160
container/hash.Set[T]
ハッシュベースのセット型。
#69230CL 745441
container/set.Set[T]
要素が比較可能なセットのための標準的なデータ型。
内部では
map[T]struct{}
を透明に使用し、並合 (Union) や共通部分 (Intersection) などの演算をサポートします。
#77052CL 724420
container/mapset
レガシーセットのヘルパー。既存 API ではセットとしての操作が難しい場合、Union や Intersection などの演算を提供します。
set.Set
のメソッドと並行して動作します。
#60630-
container/ordered.Map[K,V]
順序付きマップ。内部は現在平衡バイナリツリーを使用していますが、必須ではありません。
「マップを作成してキーをソートする」手法よりも範囲クエリなどで優れています。
#77397-
container/heap/v2.Heap
新しいヒープ実装。既存の使いにくいヒープを置き換えるジェネリックなバイナリヒープ API です。

将来の計画: 挿入順序を保証するハッシュマップ (#80194) やスタックなどの追加も検討中です。

初期実装のアプローチ: API と漸近的性能(時間計算量)を満たすことに焦点を当て、定数係数の最適化は後回しとしています。

抽象的なコレクション制約インターフェース

Map
および
Set
タイプの共有メソッドを実現するため、共通のインターフェース型が必要です。しかし、「二項式メソッド問題」のため、通常のインターフェースでは記述できません(各実装型のメソッドシグネチャが互換性を持たないため)。

そのため、F 境界多形を使用する抽象的な制約インターフェースが導入されました。

  • 非公開: 現時点で公式に公開されておりませんが、一貫性を保つための内部利用のみ可能です。
  • 将来性: 具体的なコレクション型の経験に基づき、将来的なリリースで公開される可能性があります。

インターフェース定義の例

テストにおける適合性保証のみを目的とした簡易的な再掲です。

// _AbstractCollection は要素 E の集合 C(*hash.Map, *hash.Set など)を表します。
type _AbstractCollection[E any, C _AbstractCollection[E, C]] interface {
    Clear()
    Clone() C
    Contains(E) bool
    ContainsAll(iter.Seq[E]) bool
    Len() int
    String() string
}

// _AbstractMap はキー K から値 V へのマッピング M を表します。
type _AbstractMap[K, V any, M _AbstractMap[K, V, M]] interface {
    _AbstractCollection[K, M]

    All() iter.Seq2[K, V]
    At(K) V
    Delete(K) (V, bool)
    DeleteAll(iter.Seq[K]) bool
    DeleteFunc(func(K, V) bool) bool
    Get(K) (V, bool)
    Keys() iter.Seq[K]
    Set(K, V) (V, bool)
    SetAll(iter.Seq2[K, V]) bool
    Values() iter.Seq[V]
}

// _AbstractSet は要素 E の集合 S を表します。
type _AbstractSet[E any, S _AbstractSet[E, S]] interface {
    _AbstractCollection[E, S]

    All() iter.Seq[E]
    Delete(E) bool
    DeleteAll(iter.Seq[E]) bool
    DeleteFunc(func(E) bool) bool
    Difference(S) S
    DifferenceWith(S)
    Equal(S) bool
    Insert(E) bool
    InsertAll(iter.Seq[E]) bool
    Intersection(S) S
    IntersectionWith(S)
    Intersects(S) bool
    SymmetricDifference(S) S
    SymmetricDifferenceWith(S)
    Union(S) S
    UnionWith(S)
}

汎用関数の定義例

最小限の制約型を定義することで、ユーザーが必要な操作を実装可能です。

// _TakeSet は [Take] 関数に必要な抽象的なセットを定義します。
type _TakeSet[E any, S _TakeSet[E, S]] interface {
    All() iter.Seq[E]
    Delete(E) bool
}

// Take はセットから任意の要素を取り出し返します(空の場合はゼロ値)。
func Take[S _TakeSet[E, S], E any](set S) (e E, found bool) {
    for e = range set.All() {
        found = true
        set.Delete(e)
        break
    }
    return
}

メソッド選択に関する判断基準

  • 主観性とバランス: すべての操作をインターフェースに含めると実装負担が不釣り合いになるため、実装者への影響を考慮して慎重な選択が行われています。
    • Subset
      メソッドは省略されました(高速化が必要な特殊ケースを除き、コストがかかるため)。
    • DeleteFunc
      は残されています(ツリー内の要素削除における漸近的パフォーマンス低下を防ぐため、O(n log n) を O(n) にするため)。
  • 将来の拡張: 具体的な使用状況に基づき、必要なメソッドを追加していく予定です。

その他の設計上の考察

メソッドの返戻値と再検索防止

  • 変異メソッド: コレクションサイズを変更したかどうかを報告します。
  • 置換ロジック (
    Map.Set
    /
    Map.Delete
    )
    : 既存のキーがあればその値を返し、ブール値で存在の有無も区別します(ゼロ値との混同を防ぐため)。
  • 取得メソッド (
    Get
    vs
    At
    )
    :
    At
    は式文脈での使い勝手を考慮し提供されています。

マップとセットの違い

  • マップ:
    Equal
    メソッドを持っていません(値が比較不可能になり得るため)。
  • 置換ルール:
    Map.Set
    は既存のキーを持つエントリを置換します(組み込みの
    map
    に従う)。

集合演算のパフォーマンスと実装手法

集合代数演算(Union など)は、純粋関数的に新しいセットを返す方式を採用しました。

  • 理由:
    math/big.Int
    API の経験を踏まえ、副作用や結果の忘却を防ぐためです。
  • バリエーション:
    • -With
      オプションなし: 左演算子を不変として新しいセットを返します(「便利なもの」)。
    • -With
      オプションあり: 左演算子を直接変更し、何もしません(割当効率の良いもの)。

キーセットビュー

  • KeySetView[M, K, V]
    というラッパー型により、マップ
    [K,V]
    のキーセットとして
    Set[K]
    を抽象的に満たすことができます。
  • このビューには挿入は無意味であり、パニックを引き起こします。

maps
パッケージとの機能比較

抽象 API代替手段 / 対応関係
Clear
,
Len
組み込み関数 (
clear
,
len
) で代替可能
Clone
,
DeleteFunc
,
All
,
Keys
,
Values
完全に並行 (
maps.Clone
など)
Contains
,
ContainsAll
,
DeleteAll
組み込み演算子 (
m[k]
, ループ) で代替可能(#67377 の提案も参照)
Set
prev, ok = m[k]; m[k] = newval
で代替可能

今後、「

maps.{Contains, ContainsAll, DeleteAll}
」の追加提案を検討する可能性があります。

  • Contains
    : 式文脈において
    _ , ok = s[k]
    よりも有用です。
  • ContainsAll
    ,
    DeleteAll
    : ループおよびブール値の管理を不要にする利点があります。

同じ日のほかのニュース

一覧に戻る →

2026/08/01 4:03

Hugging Face の侵入を Tailscale が阻止しなかった

## Japanese Translation: 最近のセキュリティインシデントにより、Hugging Face の AI エージェントが永続的な Tailscale 認証キーを介して侵害され、攻撃者が悪意のあるノード 181 台を生成し、Kubernetes クラスタで root アクセスを取得し、4 日間で秘密管理ストレージにある 136 キーを含むシークレットストアにアクセスできたことが明らかになりました。Tailscale そのものには脆弱性はありませんでしたが、特権の過度に付与されたエージェントが静的認証キーを使用することで、このエスケープが可能になりました。専門家は、これらを**ワークロードアイデンティティ連邦**(署名された OIDC により短期間有効なトークンを生成)または、サポートされている場合にハードウェアバインドのキーを利用するように置き換えることを推奨しています。組織もまた、エージェントがローカルテレメトリを抑制している場合でも異常を検出するために**ネットワークフローログ**を有効にすべきであり、**Tailnet Lock**などの厳格なアドミッション制御を実装する必要があります。Tailscale は文書の改善、危険なアクションに対する UI の警告の追加、デフォルト設定の微調整による将来のインシデントの防止に取り組んでおり、同社はこの点を認識しています。 --- ### 改訂サマリー(欠落していた詳細を統合): 最近のセキュリティインシデントにより、Hugging Face の AI エージェントが永続的な Tailscale 認証キーを使用して侵害される仕組みが暴露されました。攻撃者はこれらの再利用可能な認証情報を利用し、4 日間にわたり悪意のあるノード 181 台を生成し、「秘密管理ストレージの 136 キー」へのアクセスを含むシークレットを窃取しました。これは、静的なキーが「ゼロトラスト」環境であっても深刻なリスクをもたらすことを示しています。Tailscale そのものには脆弱性はありませんでしたが、デフォルトの設定により、特権の過度に付与されたエージェントが Kubernetes クラスタの root アクセスを取得することができました。このケースは、auth keys などの標準的な認証方法の危険性を浮き彫りにしており、これらは一般的ですが、継続的な AI ワークロードには不適切で不安全です。将来のエスケープを防止するため、専門家は静的認証情報を、ワークロードアイデンティティ連邦による短期間有効なトークン(または HSM の発行が利用の妨げにならない場合にハードウェアバインドのキー)に置き換えることを推奨しています。組織はまた、異常を検出するためにネットワークフローログを有効にし、動的な識別子ベースのアクセス制御へと移行する必要があります。さらに、**Tailnet Lock**による厳格なアドミッション制御の実装や、デバイスポスチャーチェックの利用によって、不明瞭なノードをより効果的に孤立させることができます。Tailscale はゼロトラストの期待にもかかわらずインシデントを引き起こしたことを認め、文書の改善、UI のナッジの追加、デフォルト設定の微調整、類似の AI 駆動によるエスケープベクトルに対する構成強化へのエンジニアリングサポートを提供することで対応することを約束しています。

2026/08/01 0:17

エレベーター

## 日本語訳: 歴史的事象シミュレーションによるエレベーターアルゴリズムの比較により、単純な反応型戦略は動的な交通状況において複雑な最適化手法よりも優れたパフォーマンスを発揮することが示されています。SCAN(1961 年に特許出願)はロビーから最上階まで移動した後で方向を反転させ、一方 LOOK は現在の方向の要求が完了する dès à présent で反転を開始し、必ずしも最上階まで到達する必要はありません。両者はどちらも中央スケジューラーに依存し、新しい要求を最も手近な稼働中のエレベーターへ割り当てます。パフォーマンスは、30 秒以内かつ 90 秒以内の到着割合といった待機時間指標で測定されます。これらの研究では、早朝ラッシュ(ロビーから上層への移動)は、一貫して特定の方向の混雑を生じるため、夜間よりも通常より悪い待機時間を引き起こすことが示されています。奥蒂斯の RSR などの高度なプラットフォームは、遅延を処理するために継続的な再最適化(5 秒ごと)を使用し、ETA、車内負荷ペナルティ、同方向への集まる回避ボーナス、方向一致ボーナス、近接アイドルボーナスといった評価要素を活用します。しかし、ベンチマーク結果では、LOOK は高流量(>7 階/分)時や小規模なビルにおいて RSR を上回る可能性があり、そのシンプルなルールが不要な停車を減らすためです。キオスクを使用した目的地割り当てシステムは、通常よりも悪い待時間を生じることが多く、この直感に反する結果は、硬直的なキオスク割り当てと、5 秒ごとの再バランスステップがその窓期内に変化する交通状況に対応できないことに起因します。極めて高層のビルで多数のエレベーターがある場合、キオスクが提供する追加情報が有益である可能性もありますが、一般的なシミュレーション結果では、完璧な効率を追求する重機的な最適化手法よりも、適応可能なルールベースの割り当てシステムを維持することで、より優れた信頼性を確保できると示唆されています。待機時間(<30 秒、<90 秒)、階数、車両数、流量(例:18/分)などの変数を実験するためのシミュレーションツールが用意されています。

2026/08/01 3:04

qm

## Japanese Translation: Quantum(QM)は、スタートアップ向けに開発された安全なマルチプレイヤージェントハネスであり、Slack と Web チャンネルと直接連携しつつ、隔離されたワークスペース内で従業員が安全にコラボレーションすることを可能にする。该平台は、耐久性のあるサンドボックス、スコープされたメモリ、そして個々のユーザーおよび共有ルーム両方に対してファイルおよびキーチェーンビューに対する厳格な制御を提供することで、重要なデータプライバシーの問題に対処しています。オープンソースの原則(MIT ライセンス)に基づいて構築され、Node 上で TypeScript と Fastify を使用して動作するヘッドレスコア API を備えた QM は、Pi、OpenCode、Codex、Claude Code など多様な AI モデルをサポートしながら、ベンダーロックインを引き起こしません。システムは、破壊的なアクションに対して硬い拒否を実装する事前宣言されたコマンドポリシーを含む 3 つの構成可能なポーズ(Strict、Auto default、Dangerous)を通じてセキュリティを確保しています。技術的には、Postgres の永続化レイヤーを利用し、デプロイは特定のディレクトリ構造(`deploy/layers/<org>/`)を介して管理され、バイト識別可能性のあるコアを組織固有のインフラストラクチャとプラグインイメージから分離します。デプロイは `qm init` CLI を使用して開始され、スキルを具現化し、GitHub の標準的なフォーク機能ではなくローカルでリポジトリをフォークすることで、組織がコードベース全体を秘密に保つことを可能にします。さらに、QM は内部データの漏洩を厳格に防止しながらアップストリームの変更をマージする特定のスキル(`update-qm` および `upstream-pr`)を通じて継続的な更新を促進します。また、プラットフォームはカスタム内部 Web アプリ、Git リポジトリから共有可能なスキル、cron を介したバックグラウンドプロセス、および管理制御をサポートしています。ドキュメントは `docs/getting-started.md` などの主要なマークダウンファイルで利用可能です。最終的には、QM はデータの完全性やセキュリティを損なうことなく、スタートアップがプライベートプロジェクトにおける強固なコラボレーションを実現できるようにし、AI を活用する方法を変革します。

Golang プロポーザル:container/ パッケージでのジェネリックコレクション型 | そっか~ニュース