カテゴリ: Go言語 更新日: 2026/03/17

Go言語のマップのキーに使える型と制限を解説!初心者でもわかるマップの基本

Go言語のマップのキーに使える型と制限を解説
Go言語のマップのキーに使える型と制限を解説

先生と生徒の会話形式で理解しよう

生徒

「先生、Go言語のマップって何でもキーに使えるんですか?どんな型が使えるか教えてほしいです。」

先生

「マップのキーに使える型には決まりがあります。少しわかりにくいので、わかりやすく説明しますね。」

生徒

「はい、お願いします!」

先生

「では、まずマップのキーとは何かから説明して、その後で使える型や制限を詳しく見ていきましょう!」

1. Go言語のマップとは?キーと値の組み合わせ

1. Go言語のマップとは?キーと値の組み合わせ
1. Go言語のマップとは?キーと値の組み合わせ

Go言語のマップは、「キー」と「値」をセットで管理するための入れ物です。よく「辞書」や「電話帳」にたとえられます。たとえば、名前(キー)を渡すと、その人の電話番号(値)が返ってくるようなイメージです。「この名前の人の情報をすぐ取り出したい」といった場面でとても役に立ちます。

もう少し噛み砕くと、キーは「探すときに使うラベル」、値は「そのラベルに対応する中身」です。同じキーは1つしか持てないので、「名前 → 電話番号」「商品コード → 在庫数」のように、1つのキーに1つの情報を結びつけるデータ構造だと考えるとイメージしやすくなります。

簡単なサンプルで、Go言語のマップがどんな動きをするのか見てみましょう。


package main

import "fmt"

func main() {
    // 名前(キー)と電話番号(値)を管理するマップを作成
    phoneBook := map[string]string{
        "山田": "090-1234-5678",
        "佐藤": "080-9876-5432",
    }

    // キーを使って値を取り出す
    fmt.Println("山田さんの電話番号:", phoneBook["山田"])

    // 存在しないキーを指定すると、空の値(この場合は空文字列)が返る
    fmt.Println("田中さんの電話番号:", phoneBook["田中"])
}

このコードでは、phoneBook というマップに「山田」「佐藤」というキーを登録し、それぞれの電話番号を値として持たせています。phoneBook["山田"]のようにキーを指定すると、対応する電話番号をすぐに取り出すことができます。一方で、まだ登録していない「田中」というキーを指定すると、何も入っていない状態(文字列なら空文字列)が返ってきます。

このように、Go言語のマップは「キーで値を素早く探すための箱」として使えるため、設定情報やユーザー情報、集計結果など、さまざまな場面で活躍します。まずは「キーと値のペアをまとめて管理する仕組み」だと押さえておくと、次の「どんな型をキーにできるのか」という話も理解しやすくなります。

2. マップのキーに使える型とは?

2. マップのキーに使える型とは?
2. マップのキーに使える型とは?

マップのキーに使える型は、Go言語では「比較できる型(比較可能な型)」に限られています。ここでいう比較とは、==(等しい)や!=(等しくない)を使って、2つの値が同じかどうかを判定できることを指します。「このキーとあのキーが同じか?」をはっきり判定できる型だけが、マップのキーとして認められているイメージです。

なぜこれが大事かというと、マップは中で「キーを見比べる」ことで値を探しているからです。たとえば、"山田"というキーで検索するとき、マップは登録されているキーと順番に比べて「同じかどうか」を判断します。この比較ができなければ、「一致したかどうか」がわからず、正しく値を取り出せません。

もう少し身近なイメージでいうと、「出席番号 → 生徒の名前」の一覧を考えるとわかりやすいです。出席番号(1, 2, 3...)は数字として==で比べられるので、そのままマップのキーにできます。一方で、「形がバラバラで比べ方が決めづらいもの」はキーに向きません。

簡単なサンプルコードで、どのようにキーが使われるか確認してみましょう。


package main

import "fmt"

func main() {
    // 整数(int)をキー、文字列を値にしたマップ
    studentIDs := map[int]string{
        1: "山田",
        2: "佐藤",
    }

    // 文字列(string)をキーにしたマップ
    scores := map[string]int{
        "国語": 80,
        "数学": 90,
    }

    fmt.Println("1番の生徒:", studentIDs[1])
    fmt.Println("数学の点数:", scores["数学"])
}

この例では、studentIDs では int がキー、scores では string がキーとして使われています。どちらも == で比較できる型なので、問題なくマップのキーとして利用できます。逆に、スライスのように簡単に比較できない型はキーには使えません(どの型が使えてどの型が使えないかは、次の項目で具体的に見ていきます)。

まずは「Go言語のマップのキーには、必ず比較可能な型が必要になる」という考え方だけ押さえておけば、このあとの詳しい説明も理解しやすくなります。

3. 具体的に使える型の例

3. 具体的に使える型の例
3. 具体的に使える型の例

では、実際にどんな型がマップのキーとして使えるのでしょうか。基本的には「比較できる型」であれば利用できます。ここでは初心者でもイメージしやすいように、それぞれの型がどんな場面で使われるのかを交えながら説明します。

  • 数値型(int, float64 など)
    出席番号や商品IDのように「番号で管理したい」場面でよく使われます。数値は==で簡単に比較できるため、マップのキーに最適です。
  • 文字列型(string)
    名前やコード名、科目名など、人が識別しやすいラベルをキーにしたい場合に向いています。もっとも使用頻度の高いキー型です。
  • ポインタ型(*int など)
    ポインタは「メモリ上の場所」を指すため、比較もメモリアドレス同士で行われます。特定のオブジェクトを識別したい場面で使われます。
  • チャネル型(chan)
    Go言語ならではの型で、並行処理を扱う際に利用します。チャネル同士の比較が可能なため、キーとしても使用できます。
  • インターフェース型(条件による)
    インターフェースの中身が比較可能な型の場合のみ、その値をキーにできます。型によっては使えない点に注意が必要です。
  • 配列型([3]int など)
    配列は長さが固定で、すべての要素が比較可能ならキーとして使えます。「3つの属性でひとまとまりの識別子を作りたい」などの用途で使われることもあります。

これらに共通するのは、いずれも「値同士を正しく比べられる」という点です。キーが比較可能であることで、マップはデータを正確に検索できるようになります。

簡単な例を見てみましょう。文字列や数値をキーにしたマップは、実際のアプリケーションでもよく使われます。


package main

import "fmt"

func main() {
    // 文字列をキーにした例
    colors := map[string]string{
        "red":   "赤",
        "blue":  "青",
        "green": "緑",
    }

    // 数値をキーにした例
    levels := map[int]string{
        1: "初心者",
        2: "中級者",
        3: "上級者",
    }

    fmt.Println(colors["blue"])  // 「青」が表示される
    fmt.Println(levels[3])       // 「上級者」が表示される
}

このように、マップは比較可能な型をキーにすることで、必要な情報を素早く取り出せる便利な仕組みになります。どの型が使えるか知っておくことで、より柔軟にデータを扱えるようになります。

4. 使えない型の例と理由

4. 使えない型の例と理由
4. 使えない型の例と理由

マップのキーには「比較できる型」が必要でしたが、残念ながら使えない型も存在します。これらは見た目が似ていても、内部の構造や性質によって比較ができないため、マップのキーには不向きです。ここでは、なぜ使えないのかを初心者にもわかりやすいように具体的に説明します。

  • スライス型([]int など)
    スライスは「長さが変わる箱」のような存在で、中身も変更できます。そのため、2つのスライスが「完全に同じかどうか」を Go が自動で判断できません。たとえば、[1,2,3][1,2,3] は見た目は同じですが、内部的には別物として扱われるため比較ができず、キーには使えません。
  • マップ型(map[string]int など)
    マップもスライスと同じく可変であり、内部構造も複雑です。内容をまるごと比較することができないため、キーとして使うことはできません。「辞書を辞書のキーにする」ようなイメージで、何が一致しているのか判断できなくなってしまいます。
  • 関数型
    関数は「動作そのもの」を表す特別な型であり、2つの関数が同じかどうかを比較することはできません。人間でいう「性格」を比べるようなもので、マップの仕組み上扱えないためキーには使えません。
  • 構造体(struct)
    構造体自体はキーに使えますが、中に比較できないフィールドが含まれている場合はキーにできません。例えば、構造体の中にスライスやマップが含まれていると、比較ができなくなってしまうためキーとして使えないケースがあります。

これらの型は共通して「中身を直接比べることができない」という特徴を持っています。マップのキーは必ず比較可能である必要があるため、こういった型は利用できないのです。

簡単な例で確認してみましょう。以下はスライスをキーにしようとしてエラーになる例です。


package main

// これはコンパイルエラーになります!
func main() {
    // スライスは比較できないためキーとして使えない
    // invalidMap := map[[]int]string{
    //     {1, 2, 3}: "NG",
    // }
}

このように、比較できない型はマップのキーには使えないという性質を理解しておくと、エラーに悩まされることが減り、マップの仕組みもより深く理解できるようになります。

5. なぜスライスやマップはキーに使えないの?

5. なぜスライスやマップはキーに使えないの?
5. なぜスライスやマップはキーに使えないの?

スライスやマップは、一見すると便利そうに見えますが、マップのキーとしては使えません。その理由は、これらの型が内部的に「可変」であり、さらに値同士を正しく比較できない仕組みになっているためです。マップのキーは「同じ」「違う」をはっきり判断できることが絶対条件なので、この条件を満たさないスライスやマップはキーとして扱えないのです。

たとえばスライスは、値そのものではなく「可変長のデータへの参照」を持つため、[]int{1,2,3} と別の []int{1,2,3} が「同じかどうか」を Go が判断できません。見た目は同じでも、中で参照している場所が違うことがあるためです。

イメージとしては、「フォルダーの住所だけを見て中身が同じか判断しようとする」ようなものです。フォルダーの住所(参照先)が違えば、中身が同じでも同じとは言えません。

簡単な例を見てみましょう。スライスをキーにしようとすると、Goはコンパイル段階でエラーを出して教えてくれます。


package main

// このコードはコンパイルエラーになります!
func main() {
    // スライスは比較できないため、キーとして利用できない
    // invalid := map[[]int]string{
    //     {1, 2, 3}: "同じに見えるけどNG",
    // }
}

また、マップ型も同じ理由で比較できません。中身が状況によって変化する可能性があるため、「完全に同じマップかどうか」を判定できないのです。マップのキーには「固定された値を持つ型」が必要ということを覚えておくと、この制限も納得しやすくなります。

まとめると、スライスやマップがキーに使えないのは、状態が変わりやすく比較ができないためです。マップの仕組みを理解するうえでも、とても重要なポイントです。

6. キーに構造体を使う場合の注意点

6. キーに構造体を使う場合の注意点
6. キーに構造体を使う場合の注意点

構造体をキーにしたい場合は、その構造体の全てのフィールドが比較可能な型である必要があります。

もし構造体の中にスライスやマップなど比較できない型が含まれていると、その構造体はキーにできません。

7. 実際のコード例

7. 実際のコード例
7. 実際のコード例

次のコードは、文字列をキーにしたマップの例です。


phoneBook := map[string]string{
    "山田": "090-1234-5678",
    "佐藤": "080-9876-5432",
}
fmt.Println(phoneBook["山田"])

一方、スライスをキーに使おうとするとエラーになります。


// エラー例:スライスをキーにするとコンパイルできません
// var invalidMap map[[]int]string

8. ポイント整理

8. ポイント整理
8. ポイント整理

Go言語のマップのキーは「比較可能な型」である必要があり、主に数値、文字列、ポインタ、配列(要素が比較可能な場合)が使えます。

スライス、マップ、関数などはキーに使えません。構造体を使う場合は、全てのフィールドが比較可能か確認しましょう。

これを知っておくと、マップの使い方やエラーの原因を理解しやすくなります。

まとめ

まとめ
まとめ

Go言語でマップを扱うときにもっとも大切になるのが、「キーとして使える型には条件がある」という点です。初めて学ぶときには、マップは自由に値を保存できる便利な仕組みという印象が先にくるため、どんな型でもキーにできると考えてしまいがちですが、実際には比較可能な型だけがキーとして使えます。なぜ比較可能であることが重要なのかというと、マップの内部ではキーをもとに一致する値を探すため、どのキーが同じでどのキーが異なるのかを正確に判定する必要があるからです。比較できない型をキーにすると、その判定そのものができなくなるため、コンパイルが通らずエラーになってしまうのです。

数値や文字列、ポインタ、配列など比較可能な型はマップのキーとして標準的に利用することができます。とくに文字列をキーにしたマップは、辞書のように情報を調べる用途に向いており、実務や学習でも最もよく使われます。名前と電話番号、ユーザーIDとプロフィール情報など、さまざまな場面で利用できるため、マップの基本を理解しておくとデータ管理の考え方が一段と広がります。一方で、スライスやマップ、関数など比較不可能な型はマップのキーとしては使えません。スライスはサイズが変わる構造であり、同じ内容のスライス同士を自動的に比較する手段がないため、Go言語では比較不可として扱われています。関数も内部状態を比較する方法が存在しないため同じ扱いとなります。このように、マップに何をキーとして使えるかを理解しておくと、プログラムを書く際に避けるべきエラーがあらかじめわかり、より安定したコードを書くことができるようになります。

また、構造体をマップのキーとして使う場面では、構造体の内部にどんな型を使っているかを意識する必要があります。構造体そのものは比較可能ですが、フィールドの中にスライスやマップなど比較できない型が含まれている場合、その構造体全体が比較不可能になります。そのため、構造体をキーとして利用したいときには、すべてのフィールドが比較可能な型であることを確認することが欠かせません。この点を理解しておけば、複雑なデータ構造を扱う際にも安全にマップを活用でき、扱える情報の幅も大きく広がります。キーとして使える型と使えない型の違いを丁寧に押さえておけば、マップ操作中のバグや意図しない挙動も避けられ、プログラム全体の品質が向上します。

ここまでの内容を踏まえると、マップを使う際には「キーが比較可能かどうか」を常に意識することが非常に重要であるとわかります。比較可能であればスムーズに値を検索でき、比較不可の場合にはコンパイル時にエラーが出て問題点を発見できます。Go言語はこの点を明確に定義しているため、型の性質を理解しながらコードを書く習慣が身につきやすくなります。実際にコードをいくつか作ってみると、マップがどれだけ強力で扱いやすいデータ構造なのかがより実感できるはずです。

マップの理解が深まるサンプルコード

以下は、比較可能な型をキーにしたマップと、構造体をキーにした例です。記事の流れに合わせて、同じクラス名やタグでまとめています。


// 比較可能な型(文字列)を使ったマップ
book := map[string]int{
    "数学": 90,
    "英語": 85,
    "国語": 88,
}
fmt.Println(book["数学"])

// 構造体をキーにする例(全フィールド比較可能)
type Point struct {
    X int
    Y int
}

location := map[Point]string{
    {X: 1, Y: 2}: "入口付近",
    {X: 3, Y: 5}: "中央エリア",
}
fmt.Println(location[Point{X: 1, Y: 2}])

文字列や数値だけでなく、構造体も条件を満たせばしっかりとキーとして利用できることがわかります。条件を丁寧にチェックしておくことで、マップの柔軟性と便利さを最大限に引き出すことができます。

先生と生徒の振り返り会話

生徒

「マップのキーに何でも使えるわけではないということがよくわかりました。比較できるかどうかが大事なんですね。」

先生

「そうです。比較できる型であれば安心してキーに使えますし、比較できない型はそもそもマップでは使えないという特徴を覚えておくと、エラーの予防になりますよ。」

生徒

「スライスやマップが使えない理由も納得できました。構造体をキーにする場合は、フィールドも含めて確認する必要があるんですね。」

先生

「その通りです。型の性質を理解しながら使うことで、マップをもっと柔軟に扱えるようになりますよ。これからいろいろなコードを書いて、自然に使いこなせるようになりましょう。」

Go言語を基礎からスッキリ学びたい人や、 文法だけでなく「実用的な使い方」まで押さえたい人には、 定番の入門書がこちらです。

基礎からわかるGo言語をAmazonで見る

※ Amazon広告リンク

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Go言語のマップのキーには、どんなデータ型が使えるのですか?

Go言語では、マップのキーに使えるのは「比較可能な型」です。数値型(intやfloat64)、文字列型(string)、ポインタ型、配列型(比較可能な要素を持つもの)、チャネル型などが該当します。
関連セミナーのご案内

【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導

「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。

本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。

具体的な開発内容と環境

【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。

【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。

この60分で得られる3つの理解

1. 環境構築の完全な理解

「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。

2. Go言語の基本構造(変数・型)

データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。

3. 読みやすいコードの書き方

ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。

※本講座は、将来的にバックエンドエンジニアクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。

セミナー画像

初めてのGo言語を一緒に学びましょう!

カテゴリの一覧へ
新着記事
New1
Go言語
Go言語のwhile的なforループの使い方!条件式ループの基本を解説
New2
Go言語
Go言語プログラムの実行方法まとめ!VSCode・ターミナルでの実行手順を解説
New3
Swift
Swift意味とは?プログラミング言語・金融・鳥の違いを徹底解説
New4
Swift
Swift 戻り値の扱い方と複数戻り値の返し方|初心者でも分かる関数の基本
人気記事
No.1
Java&Spring記事人気No1
Go言語
Go言語でリダイレクト処理を行う方法(http.Redirect)を初心者向けに解説
No.2
Java&Spring記事人気No2
Swift
Swift開発環境の構築方法を徹底解説!Xcode・Windows・Linux対応
No.3
Java&Spring記事人気No3
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.4
Java&Spring記事人気No4
Kotlin
Gradleファイル(build.gradle.kts)の書き方と役割をやさしく解説!Kotlin初心者向け完全ガイド
No.5
Java&Spring記事人気No5
Go言語
Go言語のgo.modファイル完全ガイド!初心者でもわかる仕組みと書き方
No.6
Java&Spring記事人気No6
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.7
Java&Spring記事人気No7
Go言語
Go言語で条件式を1行で書くコツ!三項演算子の代替と短縮記法
No.8
Java&Spring記事人気No8
Kotlin
Kotlinのログ出力方法を完全ガイド!LogcatとTimberでトラブルシューティング