Go
golang

golangのちょっとしたTips

はじめに

  • いろいろと気づいたことを順不同で雑多にまとめます。

概要

  • time.Unixnanosec だけ渡せばよい
  • yaml と json のkey名指定を同じタグで指定する
  • for range で取り出した要素を変更する
  • 意外と初期化しなくても使えるものたち

内容

time.Unixnanosec だけ渡せばよい

  • secnsec にわざわざ分割して渡してもいいが
冗長
now := time.Now()
unix := now.UnixNano()

sec := unix/1e9
nsec := (nsec - sec*1e9)

time.Unix(sec, nsec)
  • sec=0 にして nsec だけ渡せばOK
ok
now := time.Now()
nano := now.UnixNano()
time.Unix(0, nano)

yaml と json のkey名指定を同じタグで指定する

yaml を Unmarshal するときは go-yaml/yaml を使うことが多いと思いますが、この場合、jsonはjson, yamlはyamlでタグをそれぞれ書く必要があります。

gopkg.in/yaml.v2
type Person struct {
    FirstName string `json:"first_name" yaml:"first_name`
    LastName  string `json:"last_name" yaml:"last_name"`
}

代わりに ghodss/yaml を使うと、jsonタグで共通化できる

github.com/ghodss/yaml
type Person struct {
    FirstName string `json:"first_name"`
    LastName  string `json:"last_name"`
}

func main() {
    p := Person{
        FirstName: "Tarou",
        LastName: "Yamada",
    }

    bs, err := yaml.Unmarshal(&p)
    if err != nil {
        log.Panicf("error: %#v", err)
    }

    log.Printf("%s", bs)
    // first_name: Tarou
    // last_name: Yamada
}

for range で取り出した要素を変更する

  • 当たり前っちゃ当たり前ですが、取り出した要素をそのまま更新しても変わりません
type Person struct {
    FirstName string
    LastName  string
}

persons := []Person{
    {FirstName: "Taro", LastName: "Yamada"},
    {FirstName: "Hanako", LastName: "Tanaka"},
    {FirstName: "Ichiro", LastName: "Suzuki"},
}

for _, p := range persons {
    p.LastName = "Takahashi"
}
fmt.Println(persons)
// [{Taro Yamada} {Hanako Tanaka} {Ichiro Suzuki}]
  • 変更したければ、 persons[i] を更新する
persons = persons0
for i := range persons {
    persons[i].LastName = "Takahashi"
}
fmt.Println(persons)
// [{Taro Takahashi} {Hanako Takahashi} {Ichiro Takahashi}]
  • pointer配列の場合はそのまま変更ができる
ppersons := []*Person{
    {FirstName: "Taro", LastName: "Yamada"},
    {FirstName: "Hanako", LastName: "Tanaka"},
    {FirstName: "Ichiro", LastName: "Suzuki"},
}

for _, p := range ppersons {
    p.LastName = "Takahashi"
}
for _, p := range ppersons {
    fmt.Println(*p)
}
// {Taro Takahashi}
// {Hanako Takahashi}
// {Ichiro Takahashi}

意外と初期化しなくても使えるものたち

  • sync.Mutex
  • sync.WaitGroup
  • errgroup.Group
  • スライス

※ nilのmapは追加するとpanicするが、nilのスライスはappend可能

var slice0 []int
fmt.Printf("%#v\n", slice0) // []int(nil)
slice0 = append(slice0, 0)
fmt.Printf("%#v\n", slice0) // []int{0}

slice1 := []int{}
fmt.Printf("%#v\n", slice1) // []int{}
slice1 = append(slice1, 0)
fmt.Printf("%#v\n", slice1) // []int{0}