ghq list を高速化する PR を出した

ghq を使い始めて以来、ディレクトリ移動にしろエディタオープンにしろ ghq list に頼りっぱなしだが、最近どうも遅く感じていた。そこでボトルネックを探してみて特定の状況下で ghq list の実行速度が向上する PR を出してみたところ、無事にマージされた。

具体的には ghq で Git リポジトリだけを使っている時に、ghq list --vcs=git が速くなる。自分の手元では20~30%くらい短縮された。

せっかくなので何を試して最終的に何をやったのかを書き残す。

続きを読む

Go の 構造体のタグを取得する

備忘録。

json などで構造体のフィールドに付ける json:omitempty などのタグを取得する方法について。


構造体フィールドのタグは標準パッケージ reflect を使って実行時に取得する。

以下、構造体 Tagged のフィールド Foo に付いているタグを取得するサンプル。

package main

import (
    "fmt"
    "reflect"
)

type Tagged struct {
    Foo string `tagA:"aaa" tagB:"bbb,ccc"`
}

func main() {
    var tagged Tagged

    // 型情報を取得
    var t reflect.Type = reflect.TypeOf(tagged)

    // Foo のフィールド情報を取得
    var f reflect.StructField
    var ok bool
    f, ok = t.FieldByName("Foo")
    if !ok {
        panic("Foo is not found")
    }

    // Foo のタグを取得
    var tag reflect.StructTag
    tag = f.Tag

    // tagA の値を取得
    fmt.Printf("tagA: %#v\n", tag.Get("tagA")) // => "aaa"

    // tagB の値を取得
    fmt.Printf("tagB: %#v\n", tag.Get("tagB")) // => "aaa"

    // 存在しないタグに対しては空文字列を返す
    fmt.Printf("tagC: %#v\n", tag.Get("tagC")) // => ""

    // Lookup を使うと存在判定ができる
    _, ok = tag.Lookup("tagC")
    fmt.Printf("tagC exists: %#v\n", ok)
}