Golang PR

Go言語(Golang)のSlice操作とループを徹底解説!【初心者向け】

記事内に商品プロモーションを含む場合があります

Go言語では、
スライス(Slice)は非常に使い勝手の良いデータ構造です。

配列に似ていますが、
サイズを自由に変更できるため、
柔軟なデータ操作が可能です。

本記事では、
スライスの基本的な使い方から、
ループを用いた効率的なデータ操作について、
初心者でも理解できるように解説します。

Goのスライスとは?

スライスはGo言語で頻繁に使われるデータ型で、
配列と似たものです。

しかし、スライスは配列と違い、
サイズを動的に変更できるという利点があります。

例えば、
配列があらかじめ決まったサイズで動作するのに対して、
スライスは要素の追加や削除に応じてサイズが自動で調整されます。

スライスの作成方法

スライスを作成するには、
make関数を使う方法とスライスリテラルを使う方法があります。

package main

import "fmt"

func main() {
	s := make([]int, 5) // 長さ5のスライスを作成 [0 0 0 0 0]
	fmt.Println(s)
	t := []string{"apple", "banana", "cherry"} // スライスリテラル [apple banana cherry]
	fmt.Println(t)
}

Go Playgroundでコードを確認


上記の例では、
makeを使って5つの要素を
持つ整数スライスを作成しています。

また、tという文字列スライスはリテラルで初期化されています。

Goのループ基本操作

スライスの各要素に対して
操作を行う際、ループが欠かせません。

Go言語にはforループがあり、
繰り返し処理を簡単に行えます。

ここでは、
基本的なfor文の使い方を説明します。

Goのfor文

以下のように、
for文を使って繰り返し処理を行います。

for i := 0; i < 5; i++ {
    fmt.Println(i)  // 0, 1, 2, 3, 4 が出力される
}


このコードでは、
変数iが0から始まり、
5未満になるまで繰り返し処理が行われます。

スライスでのfor-range文

スライスをループ処理する場合、
for-range文を使うと効率的です。

for-range文を使えば、
スライス内のすべての要素に対して繰り返し処理を行い、
同時にインデックスと値を取得できます。

package main

import "fmt"

func main() {
	s := []int{1, 2, 3, 4, 5}
	for i, v := range s {
		fmt.Printf("Index: %d, Value: %d\n", i, v)
	}
}

Go Playgroundでコードを確認

このコードでは、
スライスsの各要素にアクセスし、
インデックスiと値vを同時に取得して表示しています。

スライスとループの活用方法

スライス内の要素を反復処理する

for-range文を使うと、
スライスの要素を一つ一つ処理することが可能です。

例えば、
スライス内の数値を全て合計するコードは以下の通りです。

package main

import "fmt"

func main() {
	s := []int{1, 2, 3, 4, 5}
	sum := 0
	for _, v := range s {
    		sum += v
	}
	fmt.Println("Sum:", sum)  // 出力: Sum: 15
}

Go Playgroundでコードを確認

ここでは、インデックスは使わず、
スライスの全ての値をsumに加算して合計を求めています。

ループ変数の使い方

Goでは、
for-range文で取得したインデックスや
値はそれぞれ一時的なものであり、
ループが繰り返されるたびに更新されます。

このため、ループ内で変数を操作する際は、
その値が正しく保持されているか注意が必要です。

値が変わらない問題への対処方法

for-range文を使用して
スライスの要素を操作する際、
ループ変数の扱いに誤りがあると、
値が期待通りに変わらないことがあります。

例えば、
以下のコードではvが毎回異なる値を持つはずですが、
ループ変数を適切に扱わないと期待通りに動作しません。

s := []int{1, 2, 3}
for _, v := range s {
    go func() {
        fmt.Println(v)  // すべてのゴルーチンが同じ値を出力する可能性
    }()
}

この問題を解決するには、
ループ変数をコピーすることで、
スライスの各要素を正しく扱うことができます。

s := []int{1, 2, 3}
for _, v := range s {
    vCopy := v
    go func() {
        fmt.Println(vCopy)
    }()
}

5. スライスの注意点

nilスライスとゼロ値

Goでは、
スライスはnilの状態でも使用できますが、
その挙動はゼロ長のスライスと異なる場合があります。

nilスライスとゼロ長スライスを区別することで、
コードの信頼性を高めることができます。

スライスの長さと容量

スライスの長さ(len)と
容量(cap)は、異なる概念です。

スライスの長さは実際に格納されている要素の数を示し、
容量はそのスライスが内部で使用できるメモリの最大量を示します。

これを理解しておくと、
メモリ管理を効率的に行うことができます。

まとめ

本記事では、
Go言語のスライスとループの基本について解説しました。

スライスは配列よりも柔軟に使えるため、
Go言語でのデータ操作に欠かせない存在です。

ループの使い方を理解すれば、
スライス内のデータを効率的に処理できるようになります。

ぜひ、実際にコードを試して、
スライスとループを活用してみてください!