Tag untuk suatu bidang memungkinkan Anda untuk melampirkan informasi meta ke bidang yang dapat diperoleh menggunakan refleksi. Biasanya ini digunakan untuk memberikan info transformasi tentang bagaimana bidang struct dikodekan ke atau diterjemahkan dari format lain (atau disimpan / diambil dari database), tetapi Anda dapat menggunakannya untuk menyimpan meta-info apa pun yang Anda inginkan, baik yang ditujukan untuk yang lain paket atau untuk penggunaan Anda sendiri.
Seperti disebutkan dalam dokumentasi reflect.StructTag, dengan konvensi nilai string tag adalah daftar key:"value"pasangan yang dipisahkan oleh spasi , misalnya:
type User struct {
Name string `json:"name" xml:"name"`
}
The keybiasanya menunjukkan paket yang berikutnya "value"adalah untuk, misalnya jsonkunci diproses / digunakan oleh encoding/jsonpaket.
Jika beberapa informasi dilewatkan dalam "value", biasanya ditentukan dengan memisahkannya dengan koma ( ','), misalnya
Name string `json:"name,omitempty" xml:"name"`
Biasanya nilai tanda hubung ( '-') untuk "value"sarana untuk mengecualikan bidang dari proses (misalnya dalam kasus jsonitu berarti tidak menyusun atau menghapuskan bidang itu).
Contoh mengakses tag khusus Anda menggunakan refleksi
Kita dapat menggunakan refleksi ( reflectpaket) untuk mengakses nilai tag bidang struct. Pada dasarnya kita perlu memperoleh Typestruct kita, dan kemudian kita dapat query bidang misalnya dengan Type.Field(i int)atau Type.FieldByName(name string). Metode ini mengembalikan nilai StructFieldyang menggambarkan / mewakili bidang struct; dan StructField.Tagmerupakan nilai tipe StructTagyang menggambarkan / mewakili nilai tag.
Sebelumnya kami berbicara tentang "konvensi" . Konvensi ini berarti bahwa jika Anda mengikutinya, Anda dapat menggunakan StructTag.Get(key string)metode yang mem-parsing nilai tag dan mengembalikan Anda "value"dari yang keyAnda tentukan. The Konvensi diimplementasikan / dibangun ke dalam ini Get()metode. Jika Anda tidak mengikuti konvensi, Get()tidak akan dapat menguraikan key:"value"pasangan dan menemukan apa yang Anda cari. Itu juga bukan masalah, tetapi kemudian Anda perlu mengimplementasikan logika parsing Anda sendiri.
Juga ada StructTag.Lookup()(ditambahkan pada Go 1.7) yang "seperti Get()tetapi membedakan tag yang tidak berisi kunci yang diberikan dari tag yang mengaitkan string kosong dengan kunci yang diberikan" .
Jadi mari kita lihat contoh sederhana:
type User struct {
Name string `mytag:"MyName"`
Email string `mytag:"MyEmail"`
}
u := User{"Bob", "bob@mycompany.com"}
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"))
}
Output (coba di Go Playground ):
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 memiliki presentasi tentang tag struct yang disebut:
The Many Faces of Struct Tags (slide) (dan sebuah video )
Berikut adalah daftar kunci tag yang umum digunakan:
json - Digunakan oleh encoding/jsonpaket, dirinci dijson.Marshal()
xml - Digunakan oleh encoding/xmlpaket, dirinci dixml.Marshal()
bson - Digunakan oleh gobson , dirinci dibson.Marshal()
protobuf - Digunakan oleh github.com/golang/protobuf/proto, dirinci dalam dokumen paket
yaml - Digunakan oleh gopkg.in/yaml.v2paket, dirinci diyaml.Marshal()
db - digunakan oleh github.com/jmoiron/sqlxpaket; juga digunakan oleh github.com/go-gorp/gorppaket
orm - Digunakan oleh github.com/astaxie/beego/ormpaket, dirinci di Model - Beego ORM
gorm - digunakan oleh github.com/jinzhu/gormpaket, contoh-contoh dapat ditemukan dalam dokumen mereka: Model
valid - digunakan oleh github.com/asaskevich/govalidatorpaket, contoh-contoh dapat ditemukan di halaman proyek
datastore- Digunakan oleh appengine/datastore(platform Google App Engine, layanan Datastore), dirinci di Properties
schema - Digunakan oleh github.com/gorilla/schemauntuk mengisi structdengan nilai formulir HTML, dirinci dalam dokumen paket
asn - Digunakan oleh encoding/asn1paket, dirinci di asn1.Marshal()danasn1.Unmarshal()
csv - Digunakan oleh github.com/gocarina/gocsvpaket