Go言語の多次元スライスの作り方と活用例
生徒
「先生、多次元スライスって何ですか?どうやって作るんでしょう?」
先生
「多次元スライスとは、簡単に言うと、スライスの中にスライスが入っているものです。イメージとしては、表のように行と列があるデータの管理に便利ですよ。」
生徒
「なるほど!表のようなものを作りたいときに使うんですね。具体的にはどうやって作るんですか?」
先生
「では、基本の作り方と使い方を一緒に見ていきましょう!」
1. 多次元スライスとは?
プログラミングで「多次元」とは、データが一列だけでなく、縦・横など複数の方向に並んでいる状態を指します。例えば、二次元は「縦」と「横」の2つの方向があり、学校の座席表やエクセルの表、マトリックスのようなイメージを思い浮かべると分かりやすいです。
Go言語のスライスは「動的にサイズが変わる配列」のようなものですが、多次元スライスは、そのスライスの中にさらに別のスライスが入っている入れ子構造になっています。行ごとにスライスを持つことで、表形式のデータを自然に扱うことができます。
つまり、スライスのスライスとも呼ばれ、「一次元スライスが横一列のデータ」だとすると、「多次元スライスは行と列を持つ表全体」を表しているイメージです。Go言語で多次元スライスという言葉を見かけたら、「表やリストをまとめて扱うための便利な箱」と考えると理解しやすくなります。
イメージをつかみやすくするために、簡単な二次元スライスの例を見てみましょう。
package main
import "fmt"
func main() {
// 2行3列の二次元スライス(多次元スライス)
nums := [][]int{
{1, 2, 3}, // 1行目
{4, 5, 6}, // 2行目
}
// 1行目の2列目の値を取り出して表示
fmt.Println(nums[0][1]) // 結果: 2
}
このサンプルでは、numsという変数に整数の多次元スライスを代入しています。{1, 2, 3}が1行目、{4, 5, 6}が2行目にあたり、それぞれが1つのスライスです。つまり、numsは「行(スライス)をまとめたスライス」になっています。
nums[0][1]という書き方は、「0行目のスライスの中の1番目の要素」という意味です。最初の[0]が行番号、次の[1]が列番号と考えると、表のどの位置の値を取り出しているかがイメージしやすくなります。多次元スライスの基本は、この「行と列を2つのインデックスで指定する」という考え方だと覚えておきましょう。
2. 多次元スライスの基本的な作り方
ここでは、Go言語で多次元スライス(特に二次元スライス)をどのように宣言して、どのように値を入れていくのかを確認していきます。まずは形を覚えるつもりで、ゆっくり見ていきましょう。
二次元スライスは、「行が並んだスライス」の中に「列を表すスライス」が入っているイメージです。Go言語では、次のように書いて二次元スライスを宣言します。
var matrix [][]int
これは「整数(int)を入れる二次元スライス」という型の変数matrixを用意しただけの状態です。まだ中身は何も入っていないので、「箱を用意しただけ」と考えてください。最初の[]は「行が並んだスライス」、2つ目の[]intは「各行の中にある整数のスライス」を表しています。
次に、このmatrixの中に実際の値を入れてみます。ここでは、3行3列の表をイメージした二次元スライスを初期化してみましょう。
matrix = [][]int{
{1, 2, 3}, // 1行目
{4, 5, 6}, // 2行目
{7, 8, 9}, // 3行目
}
このように書くと、{1, 2, 3}が1行目、{4, 5, 6}が2行目、{7, 8, 9}が3行目という形で、行ごとにスライスが並んだ多次元スライスになります。「外側の波カッコ」で全体の表を囲み、「内側の波カッコ」で各行を表している、とイメージすると覚えやすくなります。
もう少し具体的にイメージできるように、宣言と初期化をまとめたシンプルなサンプルプログラムも見ておきましょう。
package main
import "fmt"
func main() {
// 二次元スライスの宣言
var matrix [][]int
// 3行3列の二次元スライスを初期化
matrix = [][]int{
{1, 2, 3}, // 1行目
{4, 5, 6}, // 2行目
{7, 8, 9}, // 3行目
}
// 1行目1列目の値を表示
fmt.Println(matrix[0][0]) // 結果: 1
}
このサンプルでは、まずvar matrix [][]intで二次元スライスを宣言し、そのあとでmatrix = [][]int{...}と書いて初期化しています。値を取り出すときはmatrix[行番号][列番号]のように、かっこを2つ続けて指定します。インデックスは0から始まるので、[0][0]は「1行目1列目」、[1][2]は「2行目3列目」のようになります。
このように、二次元スライスの宣言と初期化の形をまず押さえておくと、次の章で出てくる多次元スライスの使い方やループ処理もスムーズに理解しやすくなります。
3. 多次元スライスの具体的な使い方
多次元スライスは「行と列」を持つデータを扱いたいときにとても便利です。たとえば、ゲームのマップ情報、学校の成績表、表形式のデータ、さらには画像のピクセル情報など、縦と横に並ぶデータを扱う場面でよく利用されます。特にGo言語では、スライスが柔軟に扱えるため、二次元データでも直感的に操作できます。
次のサンプルでは、二次元スライスに入っている数字を一つずつ取り出して表示しています。「行を取り出す → その中の列を取り出す」という流れが自然に書けることが分かるはずです。
package main
import "fmt"
func main() {
// 二次元スライスの準備
matrix := [][]int{
{1, 2, 3}, // 1行目
{4, 5, 6}, // 2行目
{7, 8, 9}, // 3行目
}
// 行と列を順番に取り出して表示する
for i, row := range matrix {
for j, val := range row {
fmt.Printf("matrix[%d][%d] = %d\n", i, j, val)
}
}
}
外側のforで「行」を取り出し、内側のforで「列」を取り出しています。行と列のインデックスを使うことで、表のどの位置にある値なのかが分かりやすく、表示処理やデータ加工に応用しやすいです。
このように二次元スライスを使うと、「縦×横」のデータを直感的に操作できるため、複雑な構造を扱う際にも役立ちます。まずはこの仕組みを理解しておくと、後の応用がスムーズになります。
4. 多次元スライスの初期化の注意点
多次元スライスを扱うときに覚えておきたいポイントとして、「行ごとに長さが違っても問題なく動作する」という特徴があります。これは、各行が独立したスライスとして管理されているためで、必要なデータ量に応じて柔軟に形を変えられるというメリットがあります。
例えば、次のように行によって要素数が異なるスライスをまとめて二次元スライスとして使うことができます。
matrix := [][]int{
{1, 2}, // 1行目は2つ
{3, 4, 5}, // 2行目は3つ
{6}, // 3行目は1つ
}
このように、行ごとに列数が異なる多次元スライスは「ジャグ配列(Jagged Array)」とも呼ばれます。きれいな表形式にそろえる必要がない場面では、むしろこの柔軟さが大きな利点になります。
たとえば「学生ごとにテストを受けた回数が違う」「ゲームで各プレイヤーの所持アイテム数が異なる」といったケースでは、このジャグ配列が自然にデータを表現できます。Go言語では特別な書き方をせず、そのままスライスを並べるだけで表現できるため、初心者でも扱いやすい構造といえるでしょう。
5. 動的に多次元スライスを作成する方法
多次元スライスはプログラムの実行中に動的に作ることもできます。例えば、行数だけ決めて、その後で各行の列数を決める方法です。
rows, cols := 3, 4
matrix := make([][]int, rows)
for i := 0; i < rows; i++ {
matrix[i] = make([]int, cols)
}
このコードは、3行4列の空の多次元スライスを作っています。後で値を代入できます。
6. 実際に値を代入してみよう
上で作った空の多次元スライスに値を入れてみましょう。
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
matrix[i][j] = i*cols + j + 1
}
}
このループは、左上から右下に向けて順に数字を入れる例です。
7. 多次元スライスの活用例:簡単な表の管理
多次元スライスは、例えば学校の成績表のようなデータを管理するのに便利です。行に学生、列に科目の点数を入れられます。
scores := [][]int{
{80, 90, 85}, // 学生Aの点数
{70, 75, 80}, // 学生Bの点数
{90, 95, 100}, // 学生Cの点数
}
このように多次元スライスを使うことで、行と列でデータをわかりやすく管理できます。
8. 多次元スライスを使うときのポイント
- スライスのスライスなので、行ごとに長さを変えられる。
- 初期化のときに中身を直接書くか、make関数で動的に作る方法がある。
- アクセスするときは、
matrix[行番号][列番号]のように指定する。 - ループ処理を使うと、簡単に全データを扱える。
まとめ
多次元スライスは、Go言語におけるデータ構造の中でも特に表形式のデータ管理やマトリックス処理に向いた柔軟な仕組みであり、さまざまなプログラムに応用できる便利な機能です。スライスの中に別のスライスを入れた構造であるため、行数や列数を自由に変えることができ、固定サイズの配列にはない柔軟性を備えています。今回の記事では、二次元スライスの基本的な作り方、初期化の方法、行列データへのアクセス、動的に行や列を追加する方法、そして多次元スライスが活躍する具体的な場面について、初心者にもわかりやすい形で順番に説明してきました。表形式のデータを扱ったり、複数の情報を行列として処理したりする場面は、日常的なアプリケーションでも多く登場します。 例えば、ゲームのマップ管理、画像処理、成績管理、設定情報の構造化、座標データの保持など、縦と横という概念が必要な場面では多次元スライスがとても役に立ちます。特に、行ごとに列の長さを変えられるジャグ配列の特徴は、現実世界のデータ構造に近く、複雑な情報をそのまま表現できます。動的な生成方法では、行数と列数だけ先に決めてから、それぞれの行を make で作り、あとから値を代入していくため、さまざまな入力に応じて柔軟にデータ作成が可能になります。このような仕組みは、Go言語の「必要なときに必要なだけメモリを使う」という考え方とも相性がよく、最適なデータ管理を行うために非常に便利です。 ここでは、本記事で紹介した知識を整理しながら、多次元スライスの基本と応用をまとめたサンプルコードを紹介します。このコードを見ることで、複数のスライスがどのように構造化され、どのようにアクセスできるかがより明確になるでしょう。
サンプルコード:多次元スライスの総まとめ
package main
import "fmt"
func main() {
// 3行3列の多次元スライスを作成
matrix := [][]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
fmt.Println("基本の二次元スライス:")
for i, row := range matrix {
for j, val := range row {
fmt.Printf("[%d][%d] = %d\n", i, j, val)
}
}
// 行ごとに長さの異なる多次元スライス(ジャグ配列)
jagged := [][]int{
{1, 2},
{3, 4, 5},
{6},
}
fmt.Println("\nジャグ配列:")
for i, row := range jagged {
fmt.Println("行", i, ":", row)
}
// 動的に多次元スライスを作成
rows, cols := 3, 4
dynamic := make([][]int, rows)
for i := 0; i < rows; i++ {
dynamic[i] = make([]int, cols)
}
// 値を代入
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
dynamic[i][j] = i*cols + j + 1
}
}
fmt.Println("\n動的生成した多次元スライス:")
for _, row := range dynamic {
fmt.Println(row)
}
}
多次元スライスは、配列と違いサイズ変更が容易で、各行ごとに異なる長さを持つことも可能です。ゲーム開発におけるマップ配置、統計データの保存、行と列での操作が必要な処理などに非常に向いています。使いこなせるようになると、Go言語で扱えるデータの幅がさらに広がり、より複雑な構造を簡潔に表現できるようになります。また、多次元スライスを使ったコードは視覚的にも理解しやすいため、チーム開発やコードレビューにおいても役立ちます。動的生成とジャグ配列の柔軟性を知ることで、状況に応じた使い分けができるようになることも大切です。
生徒
「多次元スライスって、最初は難しそうに感じましたけど、実際に作ってみるととても便利ですね!」
先生
「そうでしょう。表形式のデータや、多方向に広がる構造を扱うときにはとても力を発揮しますよ。」
生徒
「特にジャグ配列が自由でびっくりしました。行の長さが違ってもいいなんて、柔軟で使いやすいです!」
先生
「その通りです。現実のデータは必ずしも整っていないので、柔軟に対応できるのは大きな強みです。」
生徒
「動的に多次元スライスを作る方法も理解できました。行数と列数を後から変えられるのは便利ですね!」
先生
「動的生成を覚えると、どんな形のデータにも対応しやすくなります。これからも実際のコードで試してみてください。」
【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導
「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。
本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。
具体的な開発内容と環境
【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。
【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。
この60分で得られる3つの理解
「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。
データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。
ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。
※本講座は、将来的にバックエンドエンジニアやクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。
初めてのGo言語を一緒に学びましょう!