Go

Goのsliceやmapの型宣言省略

mapを一気に定義する場合、途中の型は省略して書いていくことができる。

    j := map[string]map[string][]string{
        "foo": {
            "aaa": {
                "bababa",
            },
        },
        "foo3": {
            "aaa": {
                "bababa",
                "bababa",
                "bababa",
                "bababa",
            },
        },
    }

これ、丁寧に書くとこうなるんだけど、

    j := map[string]map[string][]string{
        "foo": map[string][]string{
            "aaa": []string{
                "bababa",
            },
        },
        "foo3": map[string][]string{
            "aaa": []string{
                "bababa",
                "bababa",
                "bababa",
                "bababa",
            },
        },
    }

自明な部分は省略できるというわけだ。

sliceや配列でも同じように省略が効く。

type person struct {
    Name string
    Age  uint
}
// ...
    p := []person{
        {
            Name: "taro",
            Age:  10,
        },
        {
            Name: "hanako",
            Age:  12,
        },
    }
// ↓丁寧に書くと
    p := []person{
        person{
            Name: "taro",
            Age:  10,
        },
        person{
            Name: "hanako",
            Age:  12,
        },
    }

ちょっと感動したのだが、構造体のポインタであっても省略が効くようだ。&をつけたりする必要はない。

    p := []*person{
        {
            Name: "taro",
            Age:  10,
        },
        {
            Name: "hanako",
            Age:  12,
        },
    }
// ↓丁寧に書くと
    p := []*person{
        &person{
            Name: "taro",
            Age:  10,
        },
        &person{
            Name: "hanako",
            Age:  12,
        },
    }

言語仕様リンク

Within a composite literal of array, slice, or map type T, elements or map keys that are themselves composite literals may elide the respective literal type if it is identical to the element or key type of T. Similarly, elements or keys that are addresses of composite literals may elide the &T when the element or key type is *T.

https://golang.org/ref/spec#Composite_literals

というわけで、書かなかったがmapのキーに対しても同じように省略が効くらしい。

何故か構造体は省略が効かない

省略が効くのはmapとsliceとarrayだけである。構造体の中に構造体があるような場合、そこの省略は効かない…。ちょっと不便。

type Birthday struct {
    Year, Month, Day int
}

type person struct {
    Name     string
    Birthday Birthday
}
//...
    p3 := map[string]person{
        "taro": { // personの型は(mapだから)省略できている
            Name: "taro",
            Birthday: Birthday{ // Birthdayの型は省略できない
                1990, 1, 1,
            },
        },
        "hanako": {
            Name: "hanako",
            Birthday: Birthday{
                1990, 1, 2,
            },
        },
    }
    p4 := map[string]person{
        "taro":   {"taro", Birthday{1990, 1, 1}}, //この書き方でも同じ。
        "hanako": {"hanako", Birthday{1990, 1, 2}},
    }