構造体(struct)

構造体は、フィールド名とフィールド値のペアを集めて格納したものです。

  • フィールドを一意に識別するものを『フィールド名』と呼ぶ
  • フィールドの型は固定
  • フィールドの数は固定

構造体の宣言と初期化

構造体の型は次の形式で宣言します。

struct {
    フィールド名 フィールドの型
    フィールド名 フィールドの型
    ・・・
}

サンプルコードは次の通りです。

// 二次元の点を宣言
var point struct {
    X int
    Y int
}

構造体の宣言と代入を一緒にできます。

p := struct {
    X int
    Y int
}{
    X: 1,
    Y: 2,
}

型の宣言は長いので、typeで型に名前をつけておくことができます。

// Pointという名前をつける
type Point struct {
    X int
    Y int
}

func main() {
    // Pointという名前を使う
    p1 := Point{
        X: 1,
        Y: 2,
    }
    p2 := Point{
        X: 2,
        Y: 1,
    }
    fmt.Println(p1, p2)
}

構造体の初期値の設定にはいくつかの方法があります。

  • 宣言したフィールドの順に設定するなら、フィールド名を省略できる
  • 特定のフィールドだけに初期値を設定できる

サンプルコードは次の通りです。

// フィールド名を省略
p1 := Point{1, 2}
// 特定のフィールドだけに初期値を設定
p2 := Point{Y: 2}

初期値が決まっていない場合は、new関数を使った初期化もできます。 new関数の戻り値は『構造体のポインタ』になりますので注意してください。

// new関数を使う
p1 := new(Point)
// new関数と同等
p2 := &Point{}

構造体のゼロ値

構造体のゼロ値は各フィールドのゼロ値です。

type Point struct {
    X int
    Y int
}

var p Point // p == Point{X: 0, Y: 0}

フィールドへのアクセス

構造体のフィールドにアクセスには、構造体変数名.フィールド名のようにドットを使ってアクセスします。

type Point struct {
    X int
    Y int
}

func main() {
    p1 := Point{}
    p1.X = 1
    p1.Y = 2
    fmt.Println(p1.X) // 1
    fmt.Println(p1.Y) // 2
}

フィールドに構造体を宣言する

構造体のフィールドに構造体を宣言できます。 自分自身の型をフィールドの型として宣言できない点に注意してください。

type Config struct {
    Name string
    URL  URL
    // Config Config ←自分自身は宣言できない
    Config *Config // ポインタ型はOK
}

type URL struct {
    Scheme string
    Host   string
    Path   string
}

func main() {
    c := Config{
        Name: "myapp",
        URL: URL{
            Scheme: "http",
            Host:   "localhost:8080",
            Path:   "/",
        },
    }
    fmt.Println(c.Name)     // myapp
    fmt.Println(c.URL.Host) // localhost:8080
}

フィールドの埋め込み

フィールドの名前を省略して、構造体を宣言できます。

type Config struct {
    Name string
    URL  // フィールド名を省略
}

type URL struct {
    Scheme string
    Host   string
    Path   string
}

func main() {
    c := Config{
        Name: "myapp",
        URL: URL{
            Scheme: "http",
            Host:   "localhost:8080",
            Path:   "/",
        },
    }
    fmt.Println(c.Name)     // myapp
    fmt.Println(c.Host)     // localhost:8080
    fmt.Println(c.URL.Host) // localhost:8080
}