Go言語 配列

配列はGoの基本的なデータ構造で、多くのプログラミング作業で広く使用されています。配列は同じ型の要素の集まりで、連続したメモリ位置に格納され、インデックスを使ってアクセスすることができます。

Go言語 配列の構文

Goでは、配列は[n]T構文で宣言します。ここで、nは配列の要素数、Tは要素の型です。例えば、以下は5つの整数の配列を宣言しています。

var arr [5]int

Go言語 配列の初期化

また、宣言時に配列の要素の値を指定して初期化することも可能です。

arr := [5]int{1, 2, 3, 4, 5}

Go言語 配列のアクセス

配列は0から始まるインデックスを使用してアクセスすることができます。

arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(arr[0]) // 1
fmt.Println(arr[4]) // 5

Go言語 配列の推論

異なるサイズの配列を扱う必要がある場合、配列の代わりにスライスを使用する必要があります。スライスは、動的に大きくしたり小さくしたりすることができるので、より柔軟性があります。

配列の定義の仕方には、以下のような推論を用いた書き方もあります。...構文を使用すると、代入される値に基づいて配列の長さが推論されます。

arr := [...]int{1, 2, 3, 4, 5}

この例では、要素数が5の配列として推論されます。

arr := [...]int{3: 1}

上のように記述すると、3つ目の要素が1となるような要素数3の配列として推論されます。それ以外の要素は、要素の型のゼロ値で初期化されます。

Go言語 配列のループ

配列に対してループ処理を行う場合、rangeキーワードを使用してその要素に対して反復処理を行います。

arr := [5]int{1, 2, 3, 4, 5}
for i, v := range arr {
    fmt.Println("Index:", i, "Value:", v)
}

ある要素が配列に存在するかどうかを調べるには、ループと条件文を使用します。

arr := [5]int{1, 2, 3, 4, 5}
target := 3

exists := false
for _, v := range arr {
    if v == target {
        exists = true
        break
    }
}

if exists {
    fmt.Println(target, "exists in arr")
} else {
    fmt.Println(target, "does not exist in arr")
}

配列の要素を合計するには、ループと、合計を記録する変数を使用します。

arr := [5]int{1, 2, 3, 4, 5}
sum := 0

for _, v := range arr {
    sum += v
}

fmt.Println("Sum of arr:", sum) // Output: Sum of arr: 15

Go言語 配列の等価性

配列が等しいかどうかを比較する必要がある場合は、==演算子を使用することができます。ただし、この演算子は長さと型が同じ配列に対してのみ有効であることに注意してください。

arr1 := [5]int{1, 2, 3, 4, 5}
arr2 := [5]int{1, 2, 3, 4, 5}

if arr1 == arr2 {
    fmt.Println("arr1 and arr2 are equal")
}

Go言語 配列のソート

配列をソートするには、Goのsortパッケージを使用します。sortパッケージにはいくつかのソートアルゴリズムがあり、さまざまな種類の配列のソートに使用できます。以下は、整数の配列をソートする例です。

package main

import (
    "fmt"
    "sort"
)

func main() {
    arr := []int{5, 2, 4, 1, 3}
    sort.Ints(arr)
    fmt.Println(arr) // [1 2 3 4 5]
}

Go言語 配列のコピー

配列をコピーするには、copy関数を使用します。この関数は、コピー元の配列とコピー先の配列の2つの引数をとり、コピー元の配列の要素をコピー先の配列にコピーします。

arr1 := [5]int{1, 2, 3, 4, 5}
arr2 := [5]int{}

copy(arr2[:], arr1[:])
fmt.Println(arr2) // [1 2 3 4 5]

上記のコードでは、[:]がスライス式です。これは配列からスライスを作成するもので、スライスに含める要素の範囲を指定するために使用します。arr1の後のスライス式[:]は、配列arr1のすべての要素をスライスに含めることを意味します。arr2も同様です。

copy関数は2つのスライスを引数にとり、最初のスライスarr1[:]から2番目のスライスarr2[:]に要素をコピーし、arr2の要素を置き換えます。

Go言語 配列の長さ

配列の長さを求めるには、組み込みのlen関数を使用します。この関数は、引数として配列を受け取り、その長さを返します。

arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(len(arr)) // Output: 5

Go言語 配列と関数の引数

関数への引数として渡す場合は、以下のように記述します。配列内の合計値を算出してみましょう。

package main

import "fmt"

func sumArray(arr [5]int) int {
    sum := 0
    for _, v := range arr {
        sum += v
    }
    return sum
}

func main() {
    arr := [5]int{1, 2, 3, 4, 5}
    result := sumArray(arr)
    fmt.Println("Sum of arr:", result) // Sum of arr: 15
}

この例では、sumArray関数は引数として整数の配列を受け取り、その要素の合計を返します。sumArray関数の引数には配列arrが渡され、その結果がresult変数に格納されます。

他の例も見てみましょう。

func maxMinArray(arr [5]int) (int, int) {
    max := arr[0]
    min := arr[0]
    for _, v := range arr {
        if v > max {
            max = v
        }
        if v < min {
            min = v
        }
    }
    return max, min
}

arr := [5]int{1, 2, 3, 4, 5}
max, min := maxMinArray(arr)
fmt.Println("Max:", max, "Min:", min) // Max: 5 Min: 1

この例では、maxMinArray関数は引数として整数の配列を受け取り、その配列の最大値と最小値を返します。配列はmaxMinArray関数の引数として渡され、その結果はmaxとminに格納されます。

関数の戻り値として配列を返すこともできます。文字だけからなる配列を受け取り、各文字のASCII値を整数の配列として返すGoの関数の例を見てみましょう。

package main

import "fmt"

func charToAscii(chars [5]rune) [5]int {
    var asciiValues [5]int
    for i, v := range chars {
        asciiValues[i] = int(v)
    }
    return asciiValues
}

func main() {
    chars := [5]rune{'a', 'b', 'c', 'd', 'e'}
    asciiValues := charToAscii(chars)
    fmt.Println(asciiValues) // [97 98 99 100 101]
}

Go言語 配列のゼロ値

配列のゼロ値は、そのすべての要素にその基礎となるデータ型のゼロ値が設定された配列となります。

例えば、配列のデータ型がintの場合、配列のゼロ値はすべての要素を0に設定した配列となります。

var numbers [3]int
fmt.Println(numbers) // [0 0 0]

配列のデータ型がstringの場合、配列のゼロ値はすべての要素を空文字列""に設定した配列となります。

var words [3]string
fmt.Println(words) // [  ]

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート