【Golang】structのField名で気をつけるところ

Goの勉強を開始したのでメモ。
structのField名の違いで起こる挙動の違いについてまとめておきます。

(随時更新)

小文字で始まるField名は外部パッケージからのアクセスできない

ディレクトリ構成

.
|-- main.go
`-- mypkg
    `-- hoge.go

小文字の場合

hoge.go
package mypkg

type Hoge struct {
    name string
    age int
}
main.go
package main

import (
    "fmt"
    "./mypkg"
)

func main() {
    var x mypkg.Hoge
    x.name = "namae"
    x.age = 20
    fmt.Printf("x.name=%s, x.age=%d\n", x.name, x.age)
}

実行結果
各フィールドに対してundefined (cannot refer to unexported field or method name)というエラーが出る

大文字の場合

hoge.go
package mypkg

type Hoge struct {
    Name string
    Age int
}
main.go
package main

import (
    "fmt"
    "./mypkg"
)

func main() {
    var x mypkg.Hoge
    x.Name = "namae"
    x.Age = 20
    fmt.Printf("x.Name=%s, x.Age=%d\n", x.Name, x.Age)
}

実行結果
正しくx.Name=namae, x.Age=20という結果が得られる

小文字で始まるField名はencode/decodeされない

小文字の場合

main.go
package main

import (
    "fmt"
    "encoding/json"
)

type Hoge struct {
    name string `json:"name"`
    age int `json:"age"`
}

func main() {
    b := []byte(`{"name":"namae", "age":20}`)
    x := Hoge{}
    json.Unmarshal(b, &x)
    fmt.Printf("x.name=%s, x.age=%d\n", x.name, x.age)
}

実行結果
エラーは吐かないがx.name=, x.age=0が出力され、decodeされていない。

大文字の場合

main.go
package main

import (
    "fmt"
    "encoding/json"
)

type Hoge struct {
    Name string `json:"name"`
    Age int `json:"age"`
}

func main() {
    b := []byte(`{"name":"namae", "age":20}`)
    x := Hoge{}
    json.Unmarshal(b, &x)
    fmt.Printf("x.Name=%s, x.Age=%d\n", x.Name, x.Age)
}

実行結果
正しくx.Name=namae, x.Age=20という結果が得られる

まとめ

外部パッケージからのアクセス エンコード
大文字始まり 可能 される
小文字始まり 不可 されない

参考

https://qiita.com/zurazurataicho/items/4a95e0daf0d960cfc2f7

http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/index.html#unexp_struct_field_enc