1. ホーム
  2. 行く

[解決済み】Goのタグはどのような用途に使われますか?

2022-03-23 21:55:19

質問

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"
}

これは非常に短い説明ですIMO、私は誰かがこれらのタグがどのように使用されるかを私に提供することができますでしょうか?

どのように解決するのですか?

フィールド用のタグは、リフレクションを使って取得できるメタ情報をフィールドに付加することができます。通常は、構造体フィールドがどのように他の形式にエンコードされるか、または他の形式からデコードされるか(またはデータベースから保存/検索されるか)についての変換情報を提供するために使用されますが、他のパッケージまたは自分自身の使用のために意図されたどんなメタ情報も保存するために使用することができます。

のドキュメントで言及されているように 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 ] 6 タグの値を記述/表現するものです。

前回は コンベンション" . この規約は、それに従えば StructTag.Get(key string) このメソッドは、タグの値を解析して "value"key を指定します。は、その 規約 が実装され、この Get() メソッドを使用します。もし、この慣習に従わないのであれば 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では、structタグについての発表があったということです。

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

よく使われるタグキーの一覧です。