
Go言語のスライスで要素を追加したり、メモリを確保する方法を知りたいな。
今回はスライスの要素を追加したり、スライスにメモリを割り当てる操作を行っていきます。
スライスの宣言に関しては、下記の記事を参考にしてください。
【Go言語のスライス操作】append関数でスライスの要素を追加しよう
Go言語では、スライスに要素を追加する時は append()
関数を使用します。
では、プログラムで確認してみましょう。
// スライスの操作
package main
import "fmt"
func main() {
// スライスを宣言
num := []int{1, 2, 3}
fmt.Println(num)
// append関数
// スライスの最後に要素を追加する
num = append(num, 4)
fmt.Println(num)
}
// 出力結果
$ go run main.go
[1 2 3] // スライスを初期化した時の出力
[1 2 3 4] // スライスにappend関数で要素を追加した時の出力
上記のプログラムでは要素をひとつだけ追加していますが、複数同時に追加することができます。
// スライスの操作
package main
import "fmt"
func main() {
// スライスを宣言
num := []int{1, 2, 3}
fmt.Println(num)
// append関数
// スライスの最後に要素を追加する
num = append(num, 4)
fmt.Println(num)
// appendは複数渡すことができる
num = append(num, 5, 6, 7, 8, 9, 10)
fmt.Println(num)
}
// 出力結果
$ go run main.go
[1 2 3]
[1 2 3 4]
[1 2 3 4 5 6 7 8 9 10] // 要素を複数渡した出力

スライスの方が配列よりも操作に柔軟性がありますね。
【Go言語のスライス操作】for文を使ってスライスの値を取得しよう
for文を使ってスライスの値を取得しましょう。
基本的なfor文を用いた方法とrangeを使った方法の2種類です。
基本的なfor文を使ったスライスの値の取得
// スライスの値をfor文で取得する
package main
import "fmt"
func main() {
var sl []string = []string{"Golang", "Python", "C言語"}
fmt.Println(sl)
// for文の出力
for i := 0; i < len(sl); i++ {
fmt.Println(sl[i])
}
}
// 出力結果
$ go run main.go
[Golang Python C言語]
Golang
Python
C言語
rangeを使ってスライスから値を取得(インデックスと値の両方)
// rangeを使ってスライスから値を取得(インデックスと値の両方)
package main
import "fmt"
func main() {
var sl []string = []string{"Golang", "Python", "C言語"}
fmt.Println(sl)
// rangeでスライスの値を取得する
for i, v := range sl {
fmt.Println(i, v)
}
}
// 出力結果
$ go run main.go
[Golang Python C言語]
0 Golang
1 Python
2 C言語
rangeを使ってスライスから値を取得(値のみ取得)
rangeを使って値のみ取得する場合は、インデックス番号の変数部分を _ にする必要があります。
// rangeを使ってスライスから値を取得(値のみ取得)
package main
import "fmt"
func main() {
var sl []string = []string{"Golang", "Python", "C言語"}
fmt.Println(sl)
// インデックス番号不使用の場合
for _, v := range sl {
fmt.Println(v)
}
}
// 出力結果
$ go run main.go
[Golang Python C言語]
Golang
Python
C言語
rangeを使ってスライスから値を取得(インデックス番号のみ取得)
// rangeを使ってスライスから値を取得(インデックス番号のみ取得)
package main
import "fmt"
func main() {
var sl []string = []string{"Golang", "Python", "C言語"}
fmt.Println(sl)
// インデックス番号のみ取得する場合
for i := range sl {
fmt.Println(i)
}
}
// 出力結果
$ go run main.go
[Golang Python C言語]
0
1
2
【Go言語のスライス操作】make関数でスライスのメモリを割り当てよう
Go言語・入門編の学習ではメモリ容量を意識しなくてもいいのですが、メモリの制限が厳しい環境で必要になるので覚えておきましょう。
スライスのメモリを割り当てるのに使用するのが make()
関数です。
// make関数でスライスのメモリを割り当て
package main
import "fmt"
func main() {
// make関数で第一引数に要素数を指定
num2 := make([]int, 5)
// num2を出力する
fmt.Println(num2)
}
// 出力結果
$ go run main.go
[0 0 0 0 0]
make関数で生成したスライスに値を代入
上記のプログラムを元に値を代入してみましょう。
// make関数でスライスのメモリを割り当て
package main
import "fmt"
func main() {
// make関数で第一引数に要素数を指定
num2 := make([]int, 5)
// num2を出力する
fmt.Println(num2)
// 値を代入
num2[0] = 100
fmt.Println(num2)
}
// 出力結果
$ go run main.go
[0 0 0 0 0]
[100 0 0 0 0]
num2[0]
に 100
が代入されていることが確認できます。
このプログラムでは、 make()
に要素数は指定していますが容量は指定していません。
では、 num2
の要素数と容量は現在どうなっているのでしょうか?
len()関数とcap()関数について
要素数を調べる関数が len()
関数で容量を調べる関数が cap()
関数です。
では、先程のプログラムを用いて要素数と容量を確認してみましょう。
// make関数でスライスのメモリを割り当て
package main
import "fmt"
func main() {
// make関数で第1引数に要素数を指定
num2 := make([]int, 5)
// num2を出力する
fmt.Println(num2)
// len関数
// 要素数を調べる
fmt.Println("要素数は", len(num2), "です。")
// cap関数
// スライスのメモリ容量を調べる
fmt.Println("容量は", cap(num2), "です。")
}
// 出力結果
$ go run main.go
[0 0 0 0 0]
要素数は 5 です。
容量は 5 です。
上記のプログラムでは要素数を 5
に指定して容量は指定していません。
この場合、要素数と同じだけの容量が確保されているのが確認できます。
では、make関数で要素数と容量の両方を指定してみましょう。
// make関数で指定した要素数より多く要素が追加
package main
import "fmt"
func main() {
// 要素数と容量をmake関数で指定する
num3 := make([]int, 5, 10)
fmt.Println(num3)
fmt.Println("要素数は", len(num3), "です。")
fmt.Println("容量は", cap(num3), "です。")
}
// 出力結果
$ go run main.go
[0 0 0 0 0]
要素数は 5 です。
容量は 10 です。
make関数で指定した通りに要素数と容量が指定できました。
make関数で指定した要素数より多く要素が追加できる
スライスの特徴として要素数が追加できることでした。
make関数では要素数を指定できますが、それ以上に要素が追加できます。
// make関数で指定した要素数より多く要素が追加
package main
import "fmt"
func main() {
// 要素数と容量をmake関数で指定する
num3 := make([]int, 5, 10)
fmt.Println(num3)
// append関数で要素を追加する
num3 = append(num3, 1, 2, 3, 4, 5)
fmt.Println(num3)
fmt.Println("要素数は", len(num3), "です。")
fmt.Println("容量は", cap(num3), "です。")
}
// 出力結果
$ go run main.go
[0 0 0 0 0]
[0 0 0 0 0 1 2 3 4 5]
要素数は 10 です。
容量は 10 です。
make関数で要素数 5
で作成したスライスに要素を追加できていることが確認できます。
ただ、これがmake関数での注意点にもなるのです。
【Go言語のスライス操作】make関数での注意点
make関数の注意点に触れる前に、上記のプログラムを利用してさらに要素を追加してみましょう。
// make関数での注意点
package main
import "fmt"
func main() {
// 要素数と容量をmake関数で指定する
num3 := make([]int, 5, 10)
fmt.Println(num3)
// append関数で要素を追加する
num3 = append(num3, 1, 2, 3, 4, 5)
fmt.Println(num3)
fmt.Println("要素数は", len(num3), "です。")
fmt.Println("容量は", cap(num3), "です。")
// さらにappend関数で要素を追加する
num3 = append(num3, 1, 2, 3, 4, 5)
fmt.Println(num3)
fmt.Println("要素数は", len(num3), "です。")
fmt.Println("容量は", cap(num3), "です。")
}
// 出力結果
$ go run main.go
[0 0 0 0 0]
[0 0 0 0 0 1 2 3 4 5]
要素数は 10 です。
容量は 10 です。
[0 0 0 0 0 1 2 3 4 5 1 2 3 4 5]
要素数は 15 です。
容量は 20 です。 // ここが注意点!
num3
は、最初に要素数 5
容量 10
でスライスを作成しました。
指定した容量を超えた要素数を追加すると、容量が倍の量が確保されているのが確認できます。
これがmake関数での注意点で、メモリを割り当ててメモリを無駄なく使用するためにmake関数で作成したスライスですが、使い方によっては無駄なメモリを消費してしまいます。
これがmake関数での注意点で、メモリを割り当ててメモリを無駄なく使用するためにmake関数で作成したスライスですが、使い方によっては無駄なメモリを消費してしまいます。
メモリの使用制限が厳しいプログラム開発では、make関数によるスライスの作成には十分注意が必要となります。

Go言語入門の学習段階では、あまり気にしなくても大丈夫です。
【まとめ】Go言語のスライスを操作してみよう!
今回は append() 関数によるスライスへの要素の追加と、make() 関数によるメモリの割り当てを行ってみました。
では、まとめに入りましょう。
以上となります。
特に append()
関数は使用することが多いので、きちんと理解しておきましょう。
スライスに関しては、まだまだお伝えしなければいけないことがあります…
無理なく学習を進めていきましょう!
comment