Go の構造体タグの用途は何ですか? 質問する

Go の構造体タグの用途は何ですか? 質問する

の中にGo言語仕様、タグの簡単な概要について言及しています。

フィールド宣言の後にオプションの文字列リテラル タグが続く場合があり、これは対応するフィールド宣言内のすべてのフィールドの属性になります。タグはリフレクション インターフェイスを通じて表示されますが、それ以外の場合は無視されます。

// A struct corresponding to the TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers.
struct {
  microsec  uint64 "field 1"
  serverIP6 uint64 "field 2"
  process   string "field 3"
}

これは非常に短い説明だと私は思います。これらのタグがどのような用途で使われるのかを誰か教えていただけませんか?

ベストアンサー1

フィールドのタグを使用すると、リフレクションを使用して取得できるメタ情報をフィールドに添付できます。通常、これは構造体フィールドが別の形式にエンコードされるか、または別の形式からデコードされるか (またはデータベースに保存/取得されるか) に関する変換情報を提供するために使用されますが、別のパッケージ用または独自の使用を目的とした任意のメタ情報を保存するために使用できます。

の文書に記載されているようにreflect.StructTag慣例により、タグ文字列の値はスペースで区切られたkey:"value"ペアのリストになります。例:

type User struct {
    Name string `json:"name" xml:"name"`
}

key通常、後続のパッケージを表します"value"。たとえば、jsonキーはencoding/jsonパッケージ。

複数の情報を渡す場合は"value"、通常、カンマ(',')で区切って指定します。例:

Name string `json:"name,omitempty" xml:"name"`

通常、ダッシュ値 ( '-') は、"value"フィールドをプロセスから除外することを意味します (たとえば、 の場合は、jsonそのフィールドをマーシャリングまたはアンマーシャリングしないことを意味します)。

リフレクションを使用してカスタムタグにアクセスする例

反射を使うことができます(reflectパッケージ)を使用して構造体フィールドのタグ値にアクセスします。基本的には、Type構造体のフィールドをクエリすることができます。例えば、またはでクエリすることができますType.Field(i int)Type.FieldByName(name string)これらのメソッドは、StructField構造体フィールドを記述/表現し、StructField.Tag型の値であるStructTagタグ値を説明/表します。

先ほど「慣例」についてお話ししました。この慣例に従えば、StructTag.Get(key string)タグの値を解析し、指定した"value"ものを返すメソッドです。このメソッドには規則が実装/組み込まれています。規則に従わないと、ペアを解析して探しているものを見つけることができません。これも問題ではありませんが、独自の解析ロジックを実装する必要があります。keyGet()Get()key:"value"

また、StructTag.Lookup()(Go 1.7 で追加されました) これは「に似ていますGet()が、指定されたキーを含まないタグと、指定されたキーに空の文字列を関連付けるタグを区別します」

それでは簡単な例を見てみましょう:

type User struct {
    Name  string `mytag:"MyName"`
    Email string `mytag:"MyEmail"`
}

u := User{"Bob", "[email protected]"}
t := reflect.TypeOf(u)

for _, fieldName := range []string{"Name", "Email"} {
    field, found := t.FieldByName(fieldName)
    if !found {
        continue
    }
    fmt.Printf("\nField: User.%s\n", fieldName)
    fmt.Printf("\tWhole tag value : %q\n", field.Tag)
    fmt.Printf("\tValue of 'mytag': %q\n", field.Tag.Get("mytag"))
}

出力(遊び場に行く):

Field: User.Name
    Whole tag value : "mytag:\"MyName\""
    Value of 'mytag': "MyName"

Field: User.Email
    Whole tag value : "mytag:\"MyEmail\""
    Value of 'mytag': "MyEmail"

GopherCon 2015 では、構造体タグに関する次のようなプレゼンテーションが行われました。

構造体タグのさまざまな側面 (スライド)(そしてビデオ

よく使用されるタグ キーのリストは次のとおりです。

おすすめ記事