Go言語のスライス・マップ・配列の設計パターン集!実践的な使い分けを初心者向けに解説
生徒
「先生、Go言語でデータを扱うときに、スライス、マップ、配列っていろいろありますけど、どう使い分けたらいいんですか?」
先生
「それぞれ特徴があるので、目的に合わせて使い分けることが大切ですよ。具体的なパターンや工夫も一緒に説明しますね。」
生徒
「なるほど!できれば実際に使うイメージもわかると嬉しいです。」
先生
「わかりました。それでは一つずつ見ていきましょう!」
1. Go言語の配列とは?固定長の箱
配列は、決まった数のデータをひとまとめにして扱うための「箱」のような仕組みです。ここで大事なのは、箱の大きさ(要素数)を最初に決めると途中で変更できないという点です。たとえば「必ず7つのデータを扱う」とわかっている場合に向いています。
イメージしやすい例として、1週間分の気温を保存するときがあります。「月曜日から日曜日までの7日分」と決まっているので、配列を使うほうがわかりやすいです。
var temperatures [7]float64
temperatures = [7]float64{23.4, 24.1, 22.8, 21.7, 25.0, 26.5, 24.8}
配列はあらかじめ決めた数以上のデータを入れられないため、「これ以上追加したい」と思っても拡張できません。そのため、サイズが変わらないデータや、扱う数がわかっている場面で適しています。
逆に、後から数を増やしたり減らしたりしたい場合は配列だと窮屈です。そのようなケースでは、次に紹介するスライスを使うと柔軟に対応できます。
生徒
「配列は大きさが決まっているってことは、後から要素を足せないんですよね?」
先生
「その通り。配列は宣言した時点で長さが固定だよ。7なら7のまま。足したり減らしたりはできないんだ。」
生徒
「じゃあ、1週間の気温みたいに数が決まっているデータには配列が合う、と。」
先生
「うん。毎日ちょうど7個という前提があるなら配列が読みやすいし、安全だね。インデックスでtemperatures[0]からtemperatures[6]まで扱える。」
生徒
「もし8日目のデータが増えたらどうしますか?」
先生
「その場合は配列を作り直す必要がある。だから『増えるかも』と思うなら、最初からスライスを選ぶのが実用的だよ。」
生徒
「配列の初期値はどうなっていますか?」
先生
「型のゼロ値だよ。たとえばfloat64なら0.0、intなら0、stringなら空文字が入る。必要があればリテラルで最初から値を並べておくと見通しがいいね。」
生徒
「なるほど。『数が決まっている→配列』『増えるかも→スライス』って覚えておきます!」
2. スライスとは?柔軟で便利な配列のようなもの
スライスは、配列の上に乗る可変長の「動くリスト」です。配列と違って長さを後から伸ばせるので、人数や件数が決まらない場面でとても扱いやすく、実務ではまずスライスを選ぶことが多いです。内部では配列を参照しており、この内部配列を「バッキング配列」と呼びます。
基本の操作はシンプルです。appendで要素を追加し、lenで長さ、capで容量(今の配列でどこまで増やせるか)を確認できます。初期化にはリテラルのほか、makeを使うと長さと容量を指定できます。
// リテラルで作成して、あとから追加できる
names := []string{"太郎", "花子", "次郎"}
names = append(names, "三郎") // 可変長なので追加OK
fmt.Println(len(names), cap(names))
// makeで初期容量を確保しておく(成長が少し効率的)
scores := make([]int, 0, 8) // 長さ0・容量8
scores = append(scores, 10, 20, 30)
fmt.Println(len(scores), cap(scores))
スライス同士の部分取り出し(スライシング)も便利です。元データと同じバッキング配列を共有するため、書き換えが相手に影響する点だけ注意しましょう。独立させたいときはcopyで新しい領域に移します。
nums := []int{1, 2, 3, 4, 5}
part := nums[1:4] // [2 3 4] を参照(共有)
part[0] = 99 // numsも影響を受ける → [1 99 3 4 5]
// 共有を避けたいなら copy で複製する
safe := make([]int, len(part))
copy(safe, part) // safeは独立したスライスになる
このように、Go言語のスライスはappendで自在に伸ばせ、len/capで状態を把握でき、makeやcopyで性能と安全性を調整できます。人数リスト、ログの蓄積、検索結果の一時保管など「増えたり減ったりする」データにはまずスライス、と覚えておくと設計がすっきりします。
3. マップとは?キーと値のセットで管理する辞書のようなもの
マップは、ひとことで言うと「調べて取り出しやすい表」。ある情報を調べるとき、名前や番号からすぐに答えを取り出せる辞書のような仕組みです。配列やスライスは位置(0番目、1番目…)で探しますが、マップは好きな「キー」を使って目的の値を直接取り出せるため、検索に強いのが特徴です。
たとえば、社員番号(キー)に社員名(値)を対応させ、必要なときにすぐ名前を取り出せます。
employee := map[int]string{
101: "佐藤",
102: "鈴木",
103: "高橋",
}
// キーを使って素早く検索ができる
fmt.Println(employee[102]) // "鈴木"
もし存在しないキーで検索したときは、型の初期値が返ります。stringなら空文字、intなら0です。存在するか確認したいときは、2つ目の戻り値を使う書き方が便利です。
name, ok := employee[999]
if ok {
fmt.Println("見つかりました:", name)
} else {
fmt.Println("その番号の社員はいません")
}
このように、マップは「番号や名前から探す」ようなケースに強く、情報の検索・管理で大活躍します。ただし、要素の順番は保証されないので、並び順を気にせず扱える場面に向いています。
4. それぞれの使い分けパターン
4-1. 固定長で数が決まっているデータは配列
配列は「最初から数が決まっているデータ」を扱うときに向いています。途中で増減させる必要がない場合、配列のほうが構造がシンプルで、コードを読んだ人にも意図が伝わりやすくなります。
たとえば「1週間の気温」や「5教科のテスト結果」のように、扱う数がはっきりしているデータは配列がわかりやすい例です。インデックスで月曜日なら0、火曜日なら1…と決まっているため、取り扱いも迷いません。
temps := [7]float64{23.4, 24.1, 22.8, 21.7, 25.0, 26.5, 24.8}
fmt.Println(temps[0]) // 月曜日の気温
配列はサイズが変わらないため、「決まった箱に必要な値を入れていく」イメージで使うと理解がスムーズです。
4-2. サイズが変わるリストはスライス
スライスは「増えたり減ったりするデータ」を入れる箱です。配列と違って後から追加できるので、データの数が読めないときに大活躍します。実務では、ほとんどのリストデータでスライスが使われます。
たとえば、ユーザー登録があるサービスでは「人数が決まっていない」ため、1人でも1000人でも対応できるスライスが便利です。最初は空でもOKで、必要なときに追加していけます。
users := []string{} // 最初は0人
users = append(users, "太郎")
users = append(users, "花子")
fmt.Println(users) // ["太郎" "花子"] と増えていく
このように、スライスは自由に増やせるので「あとから足すかも?」というデータならスライス一択と言って良いほどです。
4-3. キーでデータを管理したいならマップ
マップは「探すのが速いデータの箱」です。名前やIDなどをキーにして、ほしい情報をすぐ取り出せるしくみが強みです。順番で探す必要がなく、ピンポイントで取り出せます。
たとえば、社員IDと名前を管理するケースを考えると、毎回「配列の何番目かな?」と探すのは大変です。マップならIDを指定するだけで一瞬で答えが取れます。
employees := map[int]string{
101: "佐藤",
102: "鈴木",
}
fmt.Println(employees[102]) // "鈴木"
存在しないデータを探したときも、確認しながら取り出せるので安全です。IDやコードで探したい場面ではマップがとても便利ですよ。
5. 実践的な設計パターンの例
5-1. 配列とスライスを組み合わせるパターン
配列で大きさの上限を決めつつ、スライスでその中の使う範囲を管理します。例えば、センサーから最大10件までデータを取得し、使う分だけスライスで操作するイメージです。
var dataArray [10]int
dataSlice := dataArray[:3] // 最初の3つだけ使う
dataSlice = append(dataSlice, 4) // 4を追加(範囲内なら可能)
5-2. マップとスライスを組み合わせるパターン
マップでキーと値を管理しつつ、スライスで順番や一覧性を保持するパターンです。Goのマップは順序が保証されないため、順番が必要な場合はスライスでキーを管理します。
m := map[string]int{"apple": 5, "banana": 2}
keys := []string{"apple", "banana"}
for _, k := range keys {
fmt.Println(k, m[k])
}
6. 使い分けのポイント
- 配列はサイズが固定で、データ数が決まっているときに使う
- スライスは可変長で、要素の追加や削除をしたいときに使う
- マップはキーと値のセットで管理し、検索が速いが順序は保証しない
- 順序を保ちたいときはスライスでキーを管理する工夫が必要
7. 初心者でも扱いやすいデータ設計を心がけよう
Go言語のスライス・マップ・配列はそれぞれ役割が異なるため、扱うデータの性質を理解して適切に選びましょう。最初は使い分けが難しいかもしれませんが、慣れるととても便利です。
今回紹介した設計パターンを参考に、実際にコードを書いて動かしてみてくださいね。
まとめ
ここまで、Go言語でよく登場する配列、スライス、マップの基本や、実際のプログラムで役に立つ使い分けパターンについて振り返りました。はじめてプログラミングに触れると、見慣れない言葉や文法がたくさん出てきて不安になることがあります。しかし、一度手を動かしてみると、それぞれの仕組みがどう動いているのかが少しずつ見えるようになり、コードを書くのが楽しくなってきます。特にデータを扱う場面では、どの構造を選ぶかによって書きやすさや読みやすさが全く変わってきます。
配列は「決まった数のデータをきちんと並べる箱」のような役割で、要素数が変わらないデータにぴったりです。スライスは「あとから増えたり減ったりできる便利な入れ物」なので、人数や件数が読めないときに重宝します。マップは「名前や番号で一瞬で探せる辞書のようなもの」で、検索が速く、扱いやすい構造です。それぞれ役割が違うため、理解しておくとプログラムがぐっと書きやすくなります。
実際の現場では、配列だけ、スライスだけ、マップだけで処理を終えるということは少なく、複数を組み合わせて使うことが多くあります。特にスライスは柔軟性が高いので、リスト形式のデータを扱うときの第一候補になります。そこにマップを加えることで検索効率がぐっと上がり、コードの見通しがよくなることもあります。
簡単なサンプルで復習しよう
ここで、配列・スライス・マップをまとめて使う簡単なコードを見てみましょう。短いプログラムですが、三つの違いがよく分かります。
package main
import "fmt"
func main() {
// 配列:決まった数の曜日を保存
days := [3]string{"月", "火", "水"}
fmt.Println("配列:", days)
// スライス:あとから名前を追加できる
users := []string{"太郎", "花子"}
users = append(users, "次郎")
fmt.Println("スライス:", users)
// マップ:名前で値段を調べる
prices := map[string]int{
"りんご": 150,
"バナナ": 120,
}
fmt.Println("マップ:", prices["りんご"])
}
三つの構造を一度に見ることで、「どんなときに何を使うか」の判断がしやすくなります。特に、スライスとマップは同時に使われることが多く、検索と並び順を両立したいときはマップとスライスを組み合わせるのが一般的です。実際に手を動かし、自分のペースで試してみることで理解が深まります。
プログラミングを学ぶうえで大切なのは、一度で完璧に覚えようとしないことです。間違えたり、わからなくなったりしても大丈夫です。その経験こそが理解につながり、いつの間にか自然と使いこなせるようになります。配列、スライス、マップは、どんなゴールを目指すかによって選び方が変わります。プログラムの目的をゆっくり考え、自分が扱いたいデータに一番合う方法を選んでみてください。
生徒
「配列、スライス、マップってどれも似たように見えましたけど、役割が違うってわかりました!」
先生
「そうだね。配列は数が決まっているとき、スライスはあとから増えたり減ったりしたいとき、マップはキーで検索したいとき。目的によって選ぶとよいよ。」
生徒
「スライスとマップは、組み合わせて使えるのも面白かったです。」
先生
「実際のアプリケーションでもよく使われる組み合わせだよ。順番を管理したいときや、表示したい並びを決めたいときにとても便利なんだ。」
生徒
「なるほど。これからは『数が決まっているか』『増えるのか』『検索したいのか』を考えて選んでみます!」
先生
「その考え方ができれば、データ構造の選び方に迷わなくなるよ。焦らず、少しずつ慣れていこう。」
この記事を読んだ人からの質問
プログラミング初心者からのよくある疑問/質問を解決します
Go言語では配列とスライスの違いがよくわかりません。初心者でも理解できる簡単な見分け方はありますか?
Go言語の配列は「サイズが変わらない固定長の箱」で、スライスは「大きさを自由に変更できる可変長のリスト」です。数が変わらないデータは配列、増えたり減ったりする可能性があるデータはスライスを使う、という考え方が最もわかりやすい使い分けのポイントです。
Go言語でスライスを使うメリットは何ですか?配列ではダメなのでしょうか?
配列は要素数を最初に決めて変更できないため、追加や削除が必要な場合は不便です。スライスは大きさを後から増やせる柔軟なデータ構造で、日常的なプログラミングではほとんどスライスを使います。Go言語でリスト状のデータを扱うときは基本的にスライスが便利です。
【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導
「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。
本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。
具体的な開発内容と環境
【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。
【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。
この60分で得られる3つの理解
「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。
データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。
ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。
※本講座は、将来的にバックエンドエンジニアやクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。
初めてのGo言語を一緒に学びましょう!