いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-221 (構造体のタグ情報(Struct Tag)を取得)

概要

Go には構造体のフィールドにタグをつけることができます。一種のメタ情報ですね。

jsonやxmlやyamlを処理する際によくお世話になる `json:"id"` とかのやつです。

基本的に利用するライブラリが定義しているタグを指定して使うことがほとんどだと思いますが、当然ながら自分で独自のタグを定義して処理することもできます。C# の 属性とか Java のアノテーションとかpython のアノテーションとかと同じ感じですね。

タグを付与することによって、自動的に動きが変わることはありません。ただのメタ情報です。 それを利用して処理するものがいて初めて意味を為します。

タグ情報はリフレクション経由で取得できます。

サンプル

何の役にも立たないサンプルですが、タグ情報を取得して何らかの処理を行うという行為をしているサンプルです。

package structtag

import (
    "reflect"
    "strings"

    "github.com/devlights/gomy/output"
)

// TagGet -- Struct Tag の内容を読み取るサンプルです。
//
// REFERENCES:
//   - https://text.baldanders.info/golang/struct-tag/
//   - https://www.digitalocean.com/community/tutorials/how-to-use-struct-tags-in-go
//   - https://qiita.com/itkr/items/9b4e8d8c6d574137443c
//   - https://logmi.jp/tech/articles/324598
func TagGet() error {
    type data struct {
        val1 string `my:"upper"`
        val2 string `my:"lower"`
    }

    // Struct Tag の情報はリフレクション経由で取得する
    d := data{val1: "hello", val2: "WORLD"}
    t := reflect.TypeOf(d)
    v := reflect.ValueOf(d)

    // フィールドに定義されているタグ情報を取得して処理
    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)

        // タグ情報取得
        tag := f.Tag.Get("my")

        // フィールドの値取得
        val := v.FieldByName(f.Name).String()

        // タグ情報に従った処理
        val2 := val
        switch tag {
        case "upper":
            val2 = strings.ToUpper(val)
        case "lower":
            val2 = strings.ToLower(val)
        }

        output.Stdoutf("[result]", "name: %v\ttag: %v\torig: %v\tconv: %v\n", f.Name, tag, val, val2)
    }

    return nil
}

実行すると以下のようになります。

gitpod /workspace/try-golang (master) $ task run
task: [run] go run . -onetime

ENTER EXAMPLE NAME: structtag_tagget

[Name] "structtag_tagget"
[result]             name: val1 tag: upper      orig: hello     conv: HELLO
[result]             name: val2 tag: lower      orig: WORLD     conv: world


[Elapsed] 44.96µs

参考情報


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。