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. マップとは?キーと値のセットで管理する辞書のようなもの
マップは、「キー」と「値」の組み合わせでデータを管理するデータ構造です。例えば、社員番号(キー)に社員の名前(値)を対応させることができます。
employee := map[int]string{
101: "佐藤",
102: "鈴木",
103: "高橋",
}
キーを使って素早く値を探せるので、検索や管理に向いています。ただし、順序は保証されません。
4. それぞれの使い分けパターン
4-1. 固定長で数が決まっているデータは配列
要素数が変わらない場合や、サイズを事前に決められる場合は配列が簡単で分かりやすいです。
例:1週間の天気予報、月の売上データなど。
4-2. サイズが変わるリストはスライス
要素の追加・削除が必要な場合はスライスが最適です。スライスは配列の上に柔軟性を持たせたものなので、Goでは基本的にリスト状のデータはスライスで扱います。
例:ユーザーのリスト、商品の注文履歴など。
4-3. キーでデータを管理したいならマップ
データを「名前」や「ID」などの特定のキーで管理したい場合はマップが便利です。検索が速く、要素の順番を気にしなくてよい場合に使います。
例:社員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言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。
具体的な開発内容と環境
【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。
【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。
この60分で得られる3つの理解
「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。
データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。
ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。
※本講座は、将来的にバックエンドエンジニアやクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。
初めてのGo言語を一緒に学びましょう!