第8章 配列
配列
Go言語における「配列」は、同じ型の要素を一定の数だけ格納するためのデータ構造です。配列の長さは固定で、宣言時に決定されます。以下にGo言語での配列の使用例をいくつか示します。
配列の宣言
配列は、要素の型と括弧内の要素数で宣言されます。
var a [5]int // int型の要素を5つ持つ配列
fmt.Println(a) // 初期値では全要素がゼロ値(この場合は0)で初期化される
配列の初期化
配列はリテラルを使用して初期化することができます。
b := [5]int{1, 2, 3, 4, 5} // 初期値を持つ配列
fmt.Println(b) // 出力: [1 2 3 4 5]
配列へのアクセスと代入
配列の特定の要素にアクセスするには、インデックスを使用します。インデックスは0から始まります。
var c [5]int
c[0] = 100
c[1] = 200
fmt.Println(c) // 出力: [100 200 0 0 0]
// 特定の要素にアクセス
fmt.Println(c[0]) // 出力: 100
配列の長さ
配列の長さは、len関数を使って取得できます。
fmt.Println(len(c)) // 出力: 5
配列の繰り返し処理
配列の要素に対する繰り返し処理は、forループを使って行います。
for i := 0; i < len(c); i++ {
fmt.Println(c[i])
}
// インデックスと値の両方が必要な場合はrangeを使用
for i, v := range c {
fmt.Println("インデックス:", i, "値:", v)
}
配列のコピー
Go言語では、配列を別の配列に代入すると、配列の内容がコピーされます。つまり、一方の配列の要素を変更しても、他方の配列には影響しません。
a := [3]int{1, 2, 3}
b := a // aの内容がbにコピーされる
b[0] = 100
fmt.Println(a) // 出力: [1 2 3]
fmt.Println(b) // 出力: [100 2 3]
配列リテラルの省略形
配列リテラルでは、要素数を省略して...を使用することができます。これにより、配列の長さは初期化時の要素数によって自動的に決定されます。
c := [...]int{4, 5, 6}
fmt.Println(c) // 出力: [4 5 6]
fmt.Println(len(c)) // 出力: 3
多次元配列
Go言語では、多次元配列もサポートされています。例えば、2次元配列を定義することができます。
var d [2][3]int
d[0][0] = 1
d[0][1] = 2
d[0][2] = 3
d[1][0] = 4
d[1][1] = 5
d[1][2] = 6
fmt.Println(d) // 出力: [[1 2 3] [4 5 6]]
配列とスライスの違い
配列と似ているがより柔軟なスライス(slice)もGo言語には存在します。スライスは配列に基づいており、動的なサイズ変更や部分的な配列の参照が可能です。
e := []int{7, 8, 9} // スライス
fmt.Println(e) // 出力: [7 8 9]
スライス
Go言語における「スライス」は、配列よりも柔軟で動的なデータ構造です。スライスは配列の上に構築され、サイズが固定されていないため、ランタイム中にサイズが変更できます。以下にスライスの使用例を示します。
スライスの基本
スライスは[]Tの形式で宣言され、Tはスライスの要素の型を示します。
// スライスの作成と初期化
s := []int{1, 2, 3}
fmt.Println(s) // 出力: [1 2 3]
// make関数によるスライスの作成
s := make([]int, 3) // 長さ3のint型のスライス
fmt.Println(s) // 出力: [0 0 0]
スライスへのアクセスと変更
スライスの要素にアクセスや変更は、配列と同様にインデックスを使用して行います。
s[0] = 100
fmt.Println(s) // 出力: [100 0 0]
スライスの追加と拡張
append関数を使って、スライスに新しい要素を追加できます。この操作は、必要に応じてスライスの容量を自動的に拡張します。
s = append(s, 4, 5)
fmt.Println(s) // 出力: [100 0 0 4 5]
スライスの長さと容量
スライスの長さと容量は、len(s)とcap(s)で取得できます。長さはスライスに含まれる要素の数を、容量はスライスの下にある配列のサイズを表します。
fmt.Println("長さ:", len(s)) // 出力: 長さ: 5
fmt.Println("容量:", cap(s)) // 出力: 容量: 6 (またはそれ以上)
スライスのスライス化
スライスは、[開始インデックス:終了インデックス]の形式で、既存のスライスから新しいスライスを作成することができます。
t := s[1:3]
fmt.Println(t) // 出力: [0 0]
マップ
Go言語における「マップ」は、キーと値のペアを格納する連想配列(または辞書)のデータ構造です。マップはキーを使用して効率的にデータを格納、検索、更新できます。以下にマップの使用例を示します。
マップの作成と初期化
マップはmap[KeyType]ValueTypeの形式で宣言されます。KeyTypeはマップのキーとなる型で、ValueTypeはマップの値の型です。
// 空のマップを作成
var m map[string]int
m = make(map[string]int)
または、リテラルを使用して初期化できます。
m := map[string]int{"apple": 5, "banana": 2}
マップへのアクセスと変更
マップに値を追加するには、キーを指定して値を代入します。
m["orange"] = 4
fmt.Println(m) // 出力: map[apple:5 banana:2 orange:4]
マップから値を取得するには、キーを指定します。
fmt.Println(m["apple"]) // 出力: 5
キーが存在するかどうかは、2つ目の戻り値で確認できます。
value, ok := m["apple"]
if ok {
fmt.Println("apple の値:", value)
} else {
fmt.Println("apple は存在しない")
}
マップからの要素の削除
delete関数を使用してマップから要素を削除できます。
delete(m, "banana")
fmt.Println(m) // 出力: map[apple:5 orange:4]
マップの繰り返し処理
forループとrangeを使用して、マップのすべてのキーと値を繰り返し処理できます。
for key, value := range m {
fmt.Println("キー:", key, "値:", value)
}
練習問題1.
整数型の要素を5つ持つ配列aを作成し、それぞれの要素に1から5までの数値を割り当ててください。その後、配列のすべての要素を出力してください。
package main
import "fmt"
func main() {
// 配列の作成と初期化
var a [5]int
// ここにコードを追加
// 配列の要素を出力
// ここにコードを追加
}
練習問題2.
整数型の要素を5つ持つ配列bが与えられたとき、配列のすべての要素の合計を計算し、出力してください。
package main
import "fmt"
func main() {
b := [5]int{1, 2, 3, 4, 5}
// ここにコードを追加
}
練習問題3.
整数型の要素を5つ持つ配列cを作成し、それを逆順にした新しい配列dを作成してください。その後、配列dのすべての要素を出力してください。
package main
import "fmt"
func main() {
c := [5]int{1, 2, 3, 4, 5}
var d [5]int
// ここにコードを追加
// 配列 d の要素を出力
// ここにコードを追加
}