データ構造
Go 言語の組み込みデータ構造:Array、Slice、Map、Struct。
Arrays
固定長のデータ列。
// 宣言
var arr [5]int // ゼロ値で初期化
arr := [5]int{1, 2, 3, 4, 5} // リテラル初期化
arr := [...]int{1, 2, 3} // 長さを自動推論
// アクセス
arr[0] = 10
fmt.Println(arr[0])
// 長さ
len(arr) // 5Slices
動的長のデータ列、Array の抽象。
Array vs Slice
| 特性 | Array | Slice |
|---|---|---|
| 長さ | 固定 | 動的 |
| 宣言 | [5]int | []int |
| 渡し方 | 配列全体をコピー | 参照を渡す |
| 比較 | == で可能 | 直接比較不可 |
Slice の内部構造
Slice は 3 つの要素を含む:
type slice struct {
ptr *array // 基礎 array へのポインタ
len int // 長さ
cap int // 容量
}
Slice の作成
// リテラル
grades := []int{10, 20, 30}
// array から
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4] // [2, 3, 4]
// make
slice := make([]int, 5) // len=5, cap=5
slice := make([]int, 5, 10) // len=5, cap=10Slice 操作
movies := []string{"Avatar", "Titanic", "Inception", "Interstellar", "The Dark Knight"}
// すべての要素をコピー(同じ基礎 array を参照)
allmovies := movies[:]
// index 0 から 2(2 を含まない)まで取得
movies[:2] // ["Avatar", "Titanic"]
// index 3 から最後まで取得
movies[3:] // ["Interstellar", "The Dark Knight"]
// append
movies = append(movies, "Tenet")
// 長さと容量
len(movies) // 6
cap(movies) // 基礎 array によるCopy Slice
src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src) // dst と src は独立Maps
キーと値のペアのデータ構造。
// 作成
m := make(map[string]int)
m := map[string]int{"a": 1, "b": 2}
// 追加/変更
m["key"] = 100
// 読み取り
value := m["key"]
// key が存在するか確認
if value, ok := m["key"]; ok {
fmt.Println("Found:", value)
}
// 削除
delete(m, "key")
// 反復
for key, value := range m {
fmt.Println(key, value)
}Map の反復順序はランダムで、順序は保証されない。
Structs
構造化されたデータ型、関連するフィールドを整理するために使用。
Go の struct は型付きフィールドのコレクションで、データをレコードとして整理するのに適している。
type Person struct {
Name string
Age int
}
// 作成
p1 := Person{Name: "Alice", Age: 30}
p2 := Person{"Bob", 25} // 定義と同じ順序が必要
p3 := &Person{Name: "Charlie"}
// アクセス
p1.Name = "Alice Updated"Struct Tags
メタデータに使用、JSON やデータベースマッピングでよく使われる。
type User struct {
ID int `json:"id" db:"user_id"`
Name string `json:"name" db:"user_name"`
Email string `json:"email,omitempty"`
Password string `json:"-"` // このフィールドを無視
CreatedAt time.Time `json:"created_at" db:"created_at"`
}| Tag | 説明 |
|---|---|
json:"name" | JSON フィールド名 |
json:",omitempty" | 空の値の場合省略 |
json:"-" | このフィールドを無視 |
db:"column" | データベースカラムマッピング |
Struct Embedding
構造体の埋め込みにより、メソッドを他の構造体に「継承」できる。
type Animal struct {
Name string
}
func (a Animal) Speak() {
fmt.Println(a.Name, "makes a sound")
}
type Dog struct {
Animal // 埋め込み
Breed string
}
func main() {
d := Dog{Animal: Animal{Name: "Buddy"}, Breed: "Golden"}
d.Speak() // Animal のメソッドを直接呼び出せる
d.Name // Animal のフィールドに直接アクセス可能
}make 関数
組み込み関数、slice、map、channel の作成に使用。
// Slice
slice := make([]int, 5) // len=5, cap=5
slice := make([]int, 5, 10) // len=5, cap=10
// Map
m := make(map[string]int)
m := make(map[string]int, 100) // 100 要素分の容量を予約
// Channel
ch := make(chan int) // バッファなし
ch := make(chan int, 10) // バッファサイズ 10Strings and Runes
- Go string は読み取り専用の byte slice
rune:type byte = uint8type rune = int32(int32のエイリアス)
- Unicode code point を表す
s := "Hello, 世界"
// 長さ
len(s) // byte 数: 13
len([]rune(s)) // 文字数: 9
// 反復
for i, r := range s {
fmt.Printf("%d: %c\n", i, r)
}
// 変換
bytes := []byte(s)
runes := []rune(s)