カテゴリ: Go言語 更新日: 2026/02/28

Go言語のスライスの容量(cap)と長さ(len)を理解しよう

Go言語のスライスの容量(cap)と長さ(len)を理解しよう
Go言語のスライスの容量(cap)と長さ(len)を理解しよう

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

生徒

「先生、Go言語のスライスって便利だけど、容量(cap)とか長さ(len)って何ですか?」

先生

「スライスの長さ(len)と容量(cap)は、スライスの大きさや使い方を理解するうえでとても大切なポイントです。簡単にいうと、長さは今使っている要素の数で、容量はスライスが内部で確保している領域の大きさのことですよ。」

生徒

「うーん、ちょっと難しいです。もう少しわかりやすく教えてください。」

先生

「では、日常生活の例え話を使って説明しますね!」

1. スライスの長さ(len)と容量(cap)って何?

1. スライスの長さ(len)と容量(cap)って何?
1. スライスの長さ(len)と容量(cap)って何?

スライスの長さ(len)は「いま実際に使っている要素の数」、容量(cap)は「そのスライスが内部で確保している最大の入れ物の大きさ」を表します。日常の例でいえば、入っているおかずの個数が長さ、弁当箱の大きさが容量です。弁当箱が大きければ、すぐに新しい箱を用意しなくてもおかずを追加できます。

もう少し踏み込むと、スライスは「配列への窓」のように動きます。長さは窓から見えている範囲容量は窓の先にどこまで余白があるかというイメージです。多くの場合はlen ≤ capになり、ゼロ値のスライスはlen=0かつcap=0です。Go言語のスライスの使い方や違いを理解するうえで、まずこの関係を押さえておくと後の操作(作成・追加・拡張)の理解がぐっと楽になります。


package main

import "fmt"

func main() {
    // 例1: リテラルで作ったスライス(長さと容量は同じになりやすい)
    fruits := []string{"りんご", "バナナ", "みかん"}
    fmt.Println("len(fruits):", len(fruits)) // 3
    fmt.Println("cap(fruits):", cap(fruits)) // 3

    // 例2: makeで長さと容量を別々に指定(余白をあらかじめ確保)
    nums := make([]int, 2, 5) // 長さ2・容量5
    fmt.Println("len(nums):", len(nums)) // 2
    fmt.Println("cap(nums):", cap(nums)) // 5
}

このように、いま入っている数=len用意してある入れ物の大きさ=capと覚えておくと迷いません。検索しやすい観点では「Go言語 スライス len cap とは」「Go スライス 容量 長さ 違い」「make で 長さ 容量 指定」といった言葉を目印にすると、関連する情報にも素早くたどり着けます。

2. Go言語でのスライスの長さ(len)と容量(cap)の確認方法

2. Go言語でのスライスの長さ(len)と容量(cap)の確認方法
2. Go言語でのスライスの長さ(len)と容量(cap)の確認方法

Go言語では、len()関数でスライスの長さを、cap()関数で容量を調べます。まずはリテラルで作ったスライスの基本的な確認から見ていきましょう。結果を見ながら「いま使っている数」と「用意されている入れ物の大きさ」の違いをつかむと、あとでappendするときの挙動も理解しやすくなります。


package main

import "fmt"

func main() {
    fruits := []string{"りんご", "バナナ", "みかん"}
    fmt.Println("長さ(len):", len(fruits)) // 実際に入っている要素の数
    fmt.Println("容量(cap):", cap(fruits)) // 確保している容量(多くは長さと同じ)
}

このコードを実行すると、


長さ(len): 3
容量(cap): 3

と表示され、リテラルで作成した直後は長さと容量が同じになりやすいことが分かります。次に、makeで「長さ」と「容量」を別々に指定して作る例です。余白を先に確保しておくと、すぐに容量拡張が起きにくくなり、要素追加がスムーズになります。


package main

import "fmt"

func main() {
    nums := make([]int, 2, 5) // 長さ2・容量5で用意
    fmt.Println("len(nums):", len(nums)) // 2(いま使っている数)
    fmt.Println("cap(nums):", cap(nums)) // 5(入れ物の大きさ)
}

このように、lencapをセットで確認すると状態が一目で分かります。検索の目印としては「Go言語 スライス 長さ 容量 確認方法」「Go スライス len cap 違い」「make append ゼロ値 nil スライス」あたりを覚えておくと、必要な情報にたどり着きやすくなります。

3. スライスの容量が大きい理由と使い方

3. スライスの容量が大きい理由と使い方
3. スライスの容量が大きい理由と使い方

スライスは動的にサイズが変わる仕組みをもつため、容量(cap)は長さ(len)より大きく確保されることがあります。これは、後から要素を追加しても毎回新しい領域を作らずに済むようにするための余裕です。イメージとしては「今入っている数=長さ」「これから入れられる余白を含む入れ物の大きさ=容量」。余白があるほど、追加が滑らかになります。

まずは、長さ3・容量5のスライスを用意して、len()cap()の違いを確かめましょう。make関数なら長さと容量を個別に指定できます。


fruits := make([]string, 3, 5) // 長さ3・容量5(余白2)
fmt.Println("長さ(len):", len(fruits)) // 3
fmt.Println("容量(cap):", cap(fruits)) // 5

この例では、要素は3つだけ入っていますが、内部では5つ分の入れ物を確保しています。つまり、appendで2個分までは容量拡張なしで素早く追加できます。これは「Go言語 スライス 容量 cap」「Go スライス 追加 append の挙動」を理解するうえで重要な観点です。

続いて、余白がある状態と、余白を使い切った後の違いを簡単に確認します(動作イメージ)。


fruits[0], fruits[1], fruits[2] = "りんご", "バナナ", "みかん"

// 余白2ぶんはそのまま追加できる(容量はまだ増えない)
fruits = append(fruits, "ぶどう") // len=4, cap=5
fruits = append(fruits, "メロン") // len=5, cap=5

// ここで余白ゼロ。さらに足すと、より大きい入れ物が内部で用意される
fruits = append(fruits, "いちご") // len=6, cap は自動拡張される可能性
fmt.Println(len(fruits), cap(fruits))

ポイントは、余白がある間の追加はスムーズで、余白を使い切ったタイミングで容量が自動拡張されること。これにより効率よくメモリを使いながら、必要に応じてスライスを伸ばせます。まずは「余白を用意する」「状況に応じて自動で広がる」という二つを押さえておくと、配列との違いがすっきり理解できます。

4. スライスに要素を追加したときの容量の変化

4. スライスに要素を追加したときの容量の変化
4. スライスに要素を追加したときの容量の変化

スライスに要素を追加するときは、append()関数を使います。もし追加で容量が足りなくなると、Go言語は自動的にもっと大きな容量の新しいスライスを作ってくれます。


fruits := make([]string, 3, 5)
fruits[0] = "りんご"
fruits[1] = "バナナ"
fruits[2] = "みかん"

fmt.Println("追加前の容量:", cap(fruits)) // 5

fruits = append(fruits, "ぶどう")
fruits = append(fruits, "メロン")

fmt.Println("追加後の容量:", cap(fruits)) // 5のまま

fruits = append(fruits, "イチゴ")
fmt.Println("さらに追加後の容量:", cap(fruits)) // 容量が増えることがある

追加前は容量5ですが、6個目を追加したときに容量が自動で増えます。これはGoが内部で効率よくメモリ管理している証拠です。

5. ポイントを整理

5. ポイントを整理
5. ポイントを整理
  • スライスの長さ(len)は、今使っている要素の数。
  • 容量(cap)は、スライスが内部で確保している最大の要素数。
  • 容量は長さより大きいことがあり、データ追加の効率化に役立つ。
  • len()cap()はスライスの状態を調べる基本関数。
  • append()で要素を追加すると容量が自動で増えることがある。

まとめ

まとめ
まとめ

ここまで、Go言語のスライスにおける長さと容量の違い、さらに要素を追加したときの変化を丁寧に確認してきました。最初は聞き慣れない言葉に戸惑うかもしれませんが、実際の動きをサンプルプログラムで見ていくと、仕組みそのものはとても素直で、初心者でも直感的に理解できるように設計されています。長さは今入っているデータの数、容量はデータを追加できる余裕の大きさという考え方をしっかり押さえておけば、実務でも迷いにくくなります。特に容量が自動で広がる仕組みは「なぜ append で簡単に追加できるのか」という疑問に対する明確な答えであり、配列とは大きく違う便利な特徴です。プログラムの世界では、目に見えないメモリの管理が裏側で動いていますが、Go言語では難しい部分をあまり意識しなくても扱えるように作られているため、初心者でも大きなトラブルなく扱えます。

また、スライスの長さと容量が確認できるということは、今どれだけのデータが入っていて、これからどれだけ追加できるかを自分で把握できるということでもあります。プログラムが大きくなると、いつのまにか容量を使い切って別の領域にコピーされることも増えますが、それが分かっていれば「なぜ動作が遅くなったのか」「どこで負荷がかかったのか」といった原因を見つけやすくなります。特に、ゲームやデータ処理のように大量のデータを扱う処理では、スライスの容量をあらかじめ多めに用意しておくことで、無駄な再確保を減らして効率の良い動作につながります。こうした視点は、これからプログラムを書くうえで役に立つ場面がとても多く、知っているかどうかでコードの質が大きく変わることもあります。

さらに、スライスは見た目は配列に似ていますが、振る舞いは全く違います。配列は固定の大きさですが、スライスは状況に合わせて伸びることができます。まるで、使いながら成長するかばんのような存在です。最初はコンパクトでも、必要になれば大きくなるので、使う側としては特別な準備をしなくても自然に扱えます。もちろん内部ではしっかりと調整が行われていますが、その作業をわざわざ自分で書かなくていいというのが、スライスが広く使われている理由です。初心者ほど、こうした自動で助けてくれる機能は大きな味方になってくれます。

実際のサンプルプログラムをもう一つ用意しておきます。よりシンプルな例で、容量が変化する場面が分かりやすくなるようにしています。手元で動かすと、スライスの中で何が起きているのかがはっきり見えるので、自信を持ってコードが書けるはずです。


package main

import "fmt"

func main() {
    letters := make([]string, 0, 2)
    fmt.Println("最初:", len(letters), cap(letters))

    letters = append(letters, "あ")
    letters = append(letters, "い")
    fmt.Println("追加後:", len(letters), cap(letters))

    letters = append(letters, "う")
    fmt.Println("容量が増えた後:", len(letters), cap(letters))
}

このように、スライスは必要に応じて容量が増えるため、最初の容量はあまり気にせずに使い始めることができます。ただ、仕組みを知っていることで、コードの読みやすさや考え方が一段階深くなります。実際の現場では、大きなデータを扱う処理が増えてくると、こうした基本が理解できているかどうかが明暗を分けることも珍しくありません。いきなり難しい使い方を覚える必要はありませんが、少しずつ触れて理解しておくことで、自然と応用ができるようになります。

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

生徒

「最初は長さと容量って同じものだと思っていました。実際に数字で比べてみると違いがよく分かりますね。」

先生

「そうなんです。見た目では分かりませんが、スライスは内部で余裕を持って管理しています。だから append でどんどん追加できるんですよ。」

生徒

「なるほど。容量の余裕がなくなると新しい入れ物に移し替えるんですね。だから容量が急に大きくなることがあるんだ。」

先生

「その通りです。細かい動きを知っていると、思い通りにプログラムを書けるようになりますよ。」

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

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

※ Amazon広告リンク

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

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

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

Go言語のスライスの長さと容量はどう違うのですか?

Go言語のスライスを勉強したばかりの初心者が混乱しやすいのが、長さと容量の違いです。長さは今入っているデータの数で、容量は内部で確保されている最大の入れ物の大きさです。この違いが分かると、appendでデータを増やしたときにどうして容量が変わるのかが理解できます。

スライスの容量が長さより大きい理由を教えてください。

Go言語のスライスでは、あとからデータを増やしやすくするために、長さより容量を少し大きく確保していることがあります。これは毎回メモリを作り直すと時間がかかるためで、あらかじめ余裕を持たせておくことで効率よく追加できます。
関連セミナーのご案内

【超入門】ゼロから始める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でトラブルシューティング