の中に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"
ものを返すメソッドです。このメソッドには規則が実装/組み込まれています。規則に従わないと、ペアを解析して探しているものを見つけることができません。これも問題ではありませんが、独自の解析ロジックを実装する必要があります。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 では、構造体タグに関する次のようなプレゼンテーションが行われました。
よく使用されるタグ キーのリストは次のとおりです。
json
- によって使用されるencoding/json
パッケージの詳細はjson.Marshal()
xml
- によって使用されるencoding/xml
パッケージの詳細はxml.Marshal()
bson
- によって使われたゴブソン詳細はbson.Marshal()
; また、モンゴゴドライバーの詳細はbson パッケージ ドキュメントprotobuf
- によって使われたgithub.com/golang/protobuf/proto
パッケージドキュメントに詳細が記載されていますyaml
- によって使用されるgopkg.in/yaml.v2
パッケージの詳細はyaml.Marshal()
db
- によって使用されるgithub.com/jmoiron/sqlx
パッケージ; 以下でも使用されるgithub.com/go-gorp/gorp
パッケージorm
- によって使用されるgithub.com/astaxie/beego/orm
パッケージの詳細はモデル – Beego ORMgorm
- によって使われたgorm.io/gorm
、例は、ドキュメントvalid
- によって使用されるgithub.com/asaskevich/govalidator
パッケージの例はプロジェクトページにありますdatastore
- によって使われたappengine/datastore
(Google App Engineプラットフォーム、データストアサービス)詳細はプロパティschema
- によって使われたgithub.com/gorilla/schema
HTMLフォームの値を入力するにはstruct
、パッケージドキュメントで詳しく説明されています。asn1
- によって使用されるencoding/asn1
パッケージの詳細はasn1.Marshal()
そしてasn1.Unmarshal()
csv
- によって使用されるgithub.com/gocarina/gocsv
パッケージenv
- によって使用されるgithub.com/caarlos0/env
パッケージ