カテゴリ: Go言語 更新日: 2026/07/29

Go言語のスライスのappend関数の使い方と応用例

Go言語のスライスのappend関数の使い方と応用例
Go言語のスライスのappend関数の使い方と応用例

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

生徒

「先生、Go言語のスライスって配列みたいだけど、append関数って何に使うんですか?」

先生

「append関数は、スライスに新しい要素を追加するときに使います。配列はサイズが決まっているけど、スライスは動的にサイズを変えられるんですよ。」

生徒

「なるほど。具体的にどうやって使うんですか?初心者でもわかるように教えてください!」

先生

「では、append関数の基本から応用まで、わかりやすく説明しますね!」

1. append関数とは?

1. append関数とは?
1. append関数とは?

Go言語のappend関数は、スライス(可変長の配列のような入れ物)に要素を足すための標準関数です。スライスには「いま入っている数」を表す長さ(length)と、「どこまで入れられるか」の容量(capacity)があり、appendは必要に応じて入れ物を広げながら新しい要素を受け止めます。

イメージは買い物カゴです。最初は小さなカゴでも、商品が増えたら店員さんが少し大きいカゴに中身ごと移してくれる感じ――あなたはただ「追加する」だけでOKです。ここで大切なのは、append新しいスライスを返すので、戻り値を受け取って使うのが基本だということです。

たとえば、空のリストに名前を1つ足すだけなら次のようになります(まずは雰囲気をつかみましょう)。


package main

import "fmt"

func main() {
    var names []string          // 空のスライスを用意
    names = append(names, "太郎") // "太郎"を追加(戻り値を代入)
    fmt.Println(names)           // ["太郎"]
}

この段階では「スライス=増やせる入れ物」「append=足して返す」というイメージが持てれば十分です。細かな使い方や複数追加の書き方は、次のセクションで丁寧に見ていきます。

2. append関数の基本的な使い方

2. append関数の基本的な使い方
2. append関数の基本的な使い方

appendは、スライスに要素を1つ足して新しいスライスを返す関数です。ポイントは「返ってきたスライスを=で受け取る」こと。受け取らないと、見た目は追加しているのに実際の変数には反映されません。


numbers := []int{1, 2, 3}
numbers = append(numbers, 4)  // 4を追加(返り値で上書きする)
fmt.Println(numbers)          // [1 2 3 4]

「再代入が必要」という感覚をつかむために、実行可能な最小例も載せます。最初はこの形をそのまま写経すると覚えやすいです。


package main

import "fmt"

func main() {
    nums := []int{1, 2, 3}
    fmt.Println("追加前:", nums) // [1 2 3]

    // 返ってきたスライスを受け取る(基本形)
    nums = append(nums, 4)
    fmt.Println("追加後:", nums) // [1 2 3 4]

    // 受け取らないと変数は変わらない(よくあるつまずき)
    tmp := []int{1, 2, 3}
    append(tmp, 4)                  // 返り値を捨ててしまっている
    fmt.Println("再代入なし:", tmp) // [1 2 3]
}

まとめると、append(元のスライス, 追加する要素)で追加し、変数 = append(...)と書くのが基本ルールです。これさえ押さえれば、スライスに値を足す操作は安心して書けます。

3. 複数の要素を一度に追加する方法

3. 複数の要素を一度に追加する方法
3. 複数の要素を一度に追加する方法

appendは要素をカンマ区切りで並べて渡すと、まとめて追加できます。基本は「返ってきたスライスを受け取る」点だけ同じです。追加した順番のまま末尾に並ぶので、並び順を保ちたいときにも安心して使えます。


numbers := []int{1, 2}
numbers = append(numbers, 3, 4, 5) // 3つまとめて追加
fmt.Println(numbers)               // [1 2 3 4 5]

実行可能な最小例でも確認してみましょう。変数に入っている値や計算結果も、そのまま並べて渡せます(型はスライスの要素型とそろえる必要があります)。


package main

import "fmt"

func main() {
    scores := []int{10}          // もともと1件
    a, b := 20, 30               // 変数の値
    scores = append(scores, a, b, 40+5) // まとめて追加&計算結果もOK
    fmt.Println("追加後:", scores)       // [10 20 30 45]

    // 並び順は渡した順に維持される
    scores = append(scores, 100, 1)
    fmt.Println("順序確認:", scores)     // [10 20 30 45 100 1]
}

ポイントは「append(スライス, 値1, 値2, ...)」という形で書き、変数 = append(...)で受け取ること。これだけで、複数の値を一度に足す操作がすっきり書けます。

4. 他のスライスをまとめて追加する方法

4. 他のスライスをまとめて追加する方法
4. 他のスライスをまとめて追加する方法

別のスライスを丸ごと足したいときは、appendの第2引数以降に...(ドット3つ)を付けます。これは「スライスbの中身を一個ずつ取り出して、順番どおりに追加してね」という合図です。型([]int[]stringなど)がそろっていることが前提です。


a := []int{1, 2}
b := []int{3, 4, 5}
a = append(a, b...)        // bの全要素をaの末尾へ展開して追加
fmt.Println(a)             // [1 2 3 4 5]

実行可能な最小例で、...の有無を体感してみましょう。append(a, b)のようにそのまま渡すのは誤りで、必ずb...と「展開」して渡します。


package main

import "fmt"

func main() {
    fruits := []string{"りんご"}
    more := []string{"みかん", "バナナ"}

    // 正しい: 中身を展開して足す
    fruits = append(fruits, more...)
    fmt.Println("展開して追加:", fruits) // ["りんご" "みかん" "バナナ"]

    // 参考: 空スライスでもOK(何も足されないだけ)
    empty := []string{}
    fruits = append(fruits, empty...)
    fmt.Println("空の展開:", fruits)     // そのまま

    // 注意: append(fruits, more) はコンパイルエラー(要素ではなくスライス自体を渡しているため)
}

覚え方はシンプルで、append(受け側, 送り側...)。これだけで「スライスの中身をまとめて追加する」書き方が安定して使えます。

5. append関数の内部で起きていること(簡単な解説)

5. append関数の内部で起きていること(簡単な解説)
5. append関数の内部で起きていること(簡単な解説)

appendはまずスライスの容量(capacity)を確認します。まだ空きがあれば、同じ入れ物(同じ配列)に要素を足して長さ(length)だけ増えるだけです。空きがないときは、より大きい入れ物(新しい配列)を用意して中身を丸ごとコピーし、その新しい入れ物を指す新しいスライスを返します。だからスライスは自動で大きくなるのです。

下の最小例では、len(長さ)とcap(容量)、そして「最初の要素の場所」をざっくり表示して、入れ物が同じかどうかを体感します。場所(アドレス)が変わったら、新しい入れ物に引っ越した合図です。


package main

import "fmt"

func addrOfFirst[T any](s []T) string {
    if len(s) == 0 {
        return "なし(空)"
    }
    return fmt.Sprintf("%p", &s[0])
}

func main() {
    nums := make([]int, 0, 2) // 長さ0・容量2で作成(少し余裕あり)
    fmt.Printf("初期  len=%d cap=%d addr=%s\n", len(nums), cap(nums), addrOfFirst(nums))

    nums = append(nums, 1)
    fmt.Printf("1件目 len=%d cap=%d addr=%s\n", len(nums), cap(nums), addrOfFirst(nums))

    nums = append(nums, 2) // まだ容量に空きがある
    fmt.Printf("2件目 len=%d cap=%d addr=%s\n", len(nums), cap(nums), addrOfFirst(nums))

    nums = append(nums, 3) // 容量が足りず拡張→新しい入れ物にコピー
    fmt.Printf("3件目 len=%d cap=%d addr=%s\n", len(nums), cap(nums), addrOfFirst(nums))
}

初期  len=0 cap=2 addr=なし(空)
1件目 len=1 cap=2 addr=0x...
2件目 len=2 cap=2 addr=0x...(同じことが多い)
3件目 len=3 cap=4 addr=0x...(変わる=引っ越し)

要点は2つだけ。空きがあれば同じ入れ物のまま足りなければ新しい入れ物を作って返す。だからこそ、appendの結果を変数に再代入して受け取るのが基本ルールになります。

6. 実際にappendで要素を追加してみる

6. 実際にappendで要素を追加してみる
6. 実際にappendで要素を追加してみる

package main

import "fmt"

func main() {
    fruits := []string{"りんご", "みかん"}
    fmt.Println(fruits)  // [りんご みかん]

    fruits = append(fruits, "バナナ")
    fmt.Println(fruits)  // [りんご みかん バナナ]

    moreFruits := []string{"ぶどう", "もも"}
    fruits = append(fruits, moreFruits...)
    fmt.Println(fruits)  // [りんご みかん バナナ ぶどう もも]
}

[りんご みかん]
[りんご みかん バナナ]
[りんご みかん バナナ ぶどう もも]

7. append関数を使うときの注意点

7. append関数を使うときの注意点
7. append関数を使うときの注意点
  • 必ず戻り値を受け取ることappendは新しいスライスを返すので、代入を忘れると元のスライスは変わりません。
  • 元のスライスの容量を超えると新しい配列が作られるので、メモリやパフォーマンスに注意が必要な場面もあります。
  • スライスの参照特性:appendで新しいスライスが作られることがあるため、複数の変数が同じスライスを参照している場合は挙動に注意してください。

8. 応用例:ユーザー入力でスライスに値を追加する

8. 応用例:ユーザー入力でスライスに値を追加する
8. 応用例:ユーザー入力でスライスに値を追加する

実際のプログラムでは、ユーザーからの入力を受け取ってスライスに追加することがあります。簡単な例を見てみましょう。


package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    var words []string

    fmt.Println("好きな言葉を入力してください。終了するにはexitと入力します。")

    for {
        fmt.Print("> ")
        if !scanner.Scan() {
            break
        }
        input := strings.TrimSpace(scanner.Text())
        if input == "exit" {
            break
        }
        words = append(words, input)
        fmt.Println("現在のリスト:", words)
    }

    fmt.Println("入力を終了しました。最終リスト:", words)
}

このプログラムでは、ユーザーが入力した言葉をどんどんスライスに追加していきます。exitと入力すると終了します。

まとめ

まとめ
まとめ

今回はGo言語のスライス操作におけるappend関数の基本から応用まで、具体的な使い方や注意点、ユーザー入力との組み合わせまで幅広く学びました。appendは、配列のような固定長の制限を超えて、柔軟にデータを扱うための非常に重要な機能です。

特に初心者にとってありがちなミスとして、「戻り値を再代入しない」「容量と参照の違いを理解しない」という点がありますが、本記事の中で紹介した小さなサンプルを使えば、それらも自然に体験しながら理解できます。また、...(ドット3つ)を使ったスライス展開の使い方や、bufio.Scannerを使ってユーザー入力を扱う応用例も合わせて覚えておくと、日常的なプログラムでも即戦力になるでしょう。

Go言語はシンプルで高速な構文が特徴ですが、そのぶん一つ一つの動きが明確であり、理解が深まるほどコードの質も上がります。今回学んだappend関数の性質を押さえておくだけで、データ構造の扱いに関する柔軟さと堅牢さがぐっと増します。

append関数で複数のユーザー入力をまとめて処理するサンプル

たとえば、ユーザーが好きな動物を入力して、最後に一覧表示するプログラムを考えてみましょう。


package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    var animals []string
    scanner := bufio.NewScanner(os.Stdin)

    fmt.Println("好きな動物を入力してください(終了は end):")

    for {
        fmt.Print("> ")
        if !scanner.Scan() {
            break
        }
        input := strings.TrimSpace(scanner.Text())
        if input == "end" {
            break
        }
        if input != "" {
            animals = append(animals, input)
        }
    }

    fmt.Println("入力された動物リスト:")
    for i, a := range animals {
        fmt.Printf("%d: %s\n", i+1, a)
    }
}

上記のように、Go言語のappendは日常的なユーザー操作と組み合わせることで、非常に実用的なデータ収集ツールにもなります。

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

生徒

「appendってただ足すだけかと思ってたけど、実は戻り値をちゃんと受け取らないといけないんですね!」

先生

「その通り!appendは新しいスライスを返す仕組みだから、変数に再代入しないと追加された結果が反映されないんだ。」

生徒

「あと、容量が足りないと新しいメモリに引っ越すっていうのも、最初は気付きにくかったです。」

先生

「そこも重要なポイントだね。特に複数のスライス変数を扱うときは、参照の共有やコピーにも注意が必要になるよ。」

生徒

「append(...b)みたいに他のスライスを展開して渡せるのも便利でした。今度、入力した値をまとめて処理するときに使ってみます!」

先生

「いい心がけだね。appendの使い方をしっかり理解しておけば、Go言語のスライス操作は怖くないよ!」

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

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

※ Amazon広告リンク

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

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

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

Go言語のスライスと配列の違いがよくわかりません。append関数は配列には使えないのですか?

Go言語の配列は最初に決めた長さを変えられない固定サイズのデータ構造ですが、Go言語のスライスは動的にサイズを増やせる柔軟なデータ構造です。append関数はスライス専用で、配列には直接使えません。append関数はスライスに新しい要素を追加し、必要に応じて容量を自動で増やしてくれるため、Go言語の実践的なプログラミングではスライスとappendを組み合わせて使うことが一般的です。

append関数を使うときに、なぜイコールで代入し直さないといけないのですか?

appendは新しいスライスを返す仕組みになっているため、イコールで受け取らずにappendを呼び出すだけでは元のスライスに変化が反映されません。初心者がよくある間違いとしてappendを呼んでも値が増えていないパターンがありますが、正しく動かすにはGo言語のスライスを再代入することが重要です。

Go言語のappend関数で複数の値を追加したいときはどうすればいいですか?

append関数はひとつの値だけでなく、複数の値をまとめて追加できます。引数をカンマ区切りで指定することで、スライスの末尾に複数の要素を連続で追加できるため、Go言語のスライス操作では効率的です。たとえば数字だけでなく文字列や構造体スライスでも同じ考え方で追加できるので、初心者でも覚えやすいポイントです。
関連セミナーのご案内

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

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

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

具体的な開発内容と環境

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

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

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

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

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

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

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

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

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

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

セミナー画像

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

カテゴリの一覧へ
新着記事
New1
TypeScript
TypeScriptのwhile文とは 初心者でもわかる繰り返し処理の基本と使い方を徹底解説
New2
Kotlin
Kotlinの制御構造まとめ!初心者が覚えるべきポイント
New3
Go言語
Go言語のスライスの容量(cap)と長さ(len)を理解しよう
New4
Kotlin
Kotlinとは何か?初心者向けにできること・特徴・インストール手順までやさしく解説
人気記事
No.1
Java&Spring記事人気No1
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.2
Java&Spring記事人気No2
Go言語
Go言語のVSCode開発環境構築完全ガイド!初心者でもわかる拡張機能と設定方法
No.3
Java&Spring記事人気No3
Kotlin
Kotlinのインストール方法まとめ!Windows・Mac・Linux別にステップ解説
No.4
Java&Spring記事人気No4
Kotlin
Kotlinの関数ドキュメンテーションコメント(KDoc)の書き方を徹底解説!初心者でもわかる丁寧なガイド
No.5
Java&Spring記事人気No5
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.6
Java&Spring記事人気No6
Kotlin
Kotlinで画面を作る!レイアウトXMLとビューの基本操作をやさしく解説
No.7
Java&Spring記事人気No7
Swift
Swift入門ガイド|基本構文と書き方をマスターしよう
No.8
Java&Spring記事人気No8
TypeScript
TypeScriptのif文とは何かを徹底解説初心者でもわかる条件分岐の基本構文と使い方

💻 作業効率アップに

ノートPCを縦置きしてデスクを広く。
省スペースで片づく定番スタンド

UGREEN 縦型スタンドをAmazonで見る

※ Amazon広告リンク