Go言語のスライス初期化方法について解説
Go言語のスライスは、動的なデータ操作が可能な便利な構造です。
この記事では、スライスの初期化方法について、シンプルな例を通して解説します。
環境が整っていれば、[]int{} や make([]int, length) といった初期化方法をすぐに試せるため、実践的な使い勝手を実感していただけるでしょう。
基本的なスライス初期化方法
スライスリテラルの利用
空のスライスの初期化
Go言語では、リテラルを利用して簡単にスライスを初期化できます。
空のスライスを作成する場合、以下のように記述します。
package main
import "fmt"
func main() {
	// 空のスライスを宣言
	var emptySlice []int
	// スライスの長さと容量を表示
	fmt.Println("空のスライスの長さ:", len(emptySlice))
	fmt.Println("空のスライスの容量:", cap(emptySlice))
}空のスライスの長さ: 0
空のスライスの容量: 0初期要素を持つスライスの作成
リテラル形式では、初期要素をそのまま記述することでスライスを初期化できます。
下記は数値型の初期要素を持つ例です。
package main
import "fmt"
func main() {
	// 数値型の初期要素を持つスライスを作成
	numbers := []int{10, 20, 30, 40}
	// スライスの内容を表示
	fmt.Println("スライス内容:", numbers)
}スライス内容: [10 20 30 40]make関数を用いた初期化
長さと容量の指定
make関数を利用すると、スライスの長さと容量を明示的に指定して初期化できます。
容量を指定することで、後からの append 操作時の再割り当てを避けることができます。
package main
import "fmt"
func main() {
	// 長さ3、容量5のスライスを生成
	numbers := make([]int, 3, 5)
	// 必要に応じて初期値を設定する
	numbers[0] = 1
	numbers[1] = 2
	numbers[2] = 3
	fmt.Println("スライスの内容:", numbers)
	fmt.Println("スライスの長さ:", len(numbers))
	fmt.Println("スライスの容量:", cap(numbers))
}スライスの内容: [1 2 3]
スライスの長さ: 3
スライスの容量: 5型別の初期化例
数値型スライスの初期化方法
数値型のスライスは、リテラルや make関数で初期化できます。
ここでは、リテラル形式の例を示します。
package main
import "fmt"
func main() {
	// 整数型スライスの初期化
	intSlice := []int{5, 10, 15, 20}
	fmt.Println("整数型スライス:", intSlice)
}整数型スライス: [5 10 15 20]文字列型スライスの初期化方法
文字列型のスライスも同様にリテラルで初期化可能です。
下記の例では、文字列型のリストを作成しています。
package main
import "fmt"
func main() {
	// 文字列型スライスの初期化
	stringSlice := []string{"apple", "banana", "cherry"}
	fmt.Println("文字列型スライス:", stringSlice)
}文字列型スライス: [apple banana cherry]構造体スライスの初期化方法
構造体を用いたスライスも、リテラルで初期化することができます。
ここでは、シンプルな構造体 Person を例に、スライスを初期化する方法を示します。
package main
import "fmt"
// Person構造体は人物情報を管理するための構造体です。
type Person struct {
	Name string // 名前
	Age  int    // 年齢
}
func main() {
	// 構造体のスライスを初期化
	people := []Person{
		{"太郎", 25},
		{"花子", 30},
	}
	fmt.Println("構造体スライス:", people)
}構造体スライス: [{太郎 25} {花子 30}]初期化時のパフォーマンスとメモリ管理
キャパシティ設定の工夫
スライスを make関数で初期化する際には、長さだけでなく容量も指定することでメモリ再割当の回数を削減し、パフォーマンスを向上させることができます。
例えば、要素数があらかじめ予測できる場合は、余裕をもたせた容量を指定しておくと良いです。
package main
import "fmt"
func main() {
	// 最初から十分な容量を持ったスライスを作成する例
	// 要素数は4だが、容量は10に設定
	data := make([]int, 4, 10)
	data[0] = 1
	data[1] = 2
	data[2] = 3
	data[3] = 4
	fmt.Println("初期化時のスライス:", data)
	fmt.Println("長さ:", len(data))
	fmt.Println("容量:", cap(data))
}初期化時のスライス: [1 2 3 4]
長さ: 4
容量: 10メモリ再利用のポイント
スライスの再利用を考える場合、append関数で要素を追加すると容量が足りなくなった際に新たな配列が生成される場合があります。
このような状況を避けるため、スライスの容量を適切に管理することが大切です。
たとえば、使い回しをする際には、スライスをリセットして再利用することが有効です。
package main
import "fmt"
func main() {
	// 最初に十分な容量を確保してスライスを初期化
	buffer := make([]int, 0, 8)
	// 要素を追加する例
	for i := 0; i < 5; i++ {
		buffer = append(buffer, i)
	}
	fmt.Println("追加後のスライス:", buffer)
	fmt.Println("長さ:", len(buffer))
	fmt.Println("容量:", cap(buffer))
}追加後のスライス: [0 1 2 3 4]
長さ: 5
容量: 8スライス操作との連携
append関数との併用
append関数はスライスに要素を追加する際によく使用されます。
上記の例でも使用していますが、append によってスライス内の配列が自動的に拡張されるため、開発時の柔軟な操作が可能です。
package main
import "fmt"
func main() {
	// 数値型スライスの初期化(空のスライス)
	numbers := []int{}
	// append関数を利用して要素を追加
	numbers = append(numbers, 100)
	numbers = append(numbers, 200)
	numbers = append(numbers, 300)
	fmt.Println("append後のスライス:", numbers)
}append後のスライス: [100 200 300]copy関数を利用した部分操作
copy関数は、スライス間で要素をコピーする際に使用します。
片方のスライスが元のデータを保持したまま、別のスライスに部分要素をコピーする場合に利用でき、要素数や位置を自由に調整できます。
package main
import "fmt"
func main() {
	// 元のスライスを定義
	src := []int{10, 20, 30, 40, 50}
	// コピー先のスライスを初期化(長さ3のスライスを作成)
	dst := make([]int, 3)
	// srcの先頭3要素をdstにコピー
	copy(dst, src)
	fmt.Println("コピー元のスライス:", src)
	fmt.Println("コピー先のスライス:", dst)
}コピー元のスライス: [10 20 30 40 50]
コピー先のスライス: [10 20 30]まとめ
この記事では、スライスの初期化方法やリテラル、make関数、型別の初期化例、メモリ管理、appendやcopy関数の連携について解説しました。
総括すると、スライスの正しい初期化と効率的な操作方法が理解でき、Go言語でのコーディングがより堅牢に実装できる内容です。
ぜひ、示したサンプルコードを自身の環境で実行して試してみてください。