データ構造

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) // 5

Slices

動的どうてきちょうのデータれつ、Array の抽象ちゅうしょう

Array vs Slice

特性とくせいArraySlice
なが固定こてい動的どうてき
宣言せんげん[5]int[]int
わたかた配列はいれつ全体ぜんたいをコピー参照さんしょうわた
比較ひかく==可能かのう直接ちょくせつ比較ひかく不可ふか

Slice の内部構造

Slice は 3 つの要素ようそふくむ:

type slice struct {
    ptr *array  // 基礎 array へのポインタ
    len int     // 長さ
    cap int     // 容量
}
Slice Internal Structure

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=10

Slice 操作

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) // バッファサイズ 10

Strings and Runes

  • Go string は専用せんようの byte slice
  • rune
    • type byte = uint8
    • type rune = int32int32 のエイリアス)
  • 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)

関連トピック