Dalam Spesifikasi Bahasa Go , ini menyebutkan ikhtisar singkat dari tag:
Deklarasi bidang dapat diikuti oleh tag literal string opsional, yang menjadi atribut untuk semua bidang dalam deklarasi bidang terkait. Tag dibuat terlihat melalui antarmuka refleksi tetapi sebaliknya diabaikan.
// 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" }
Ini adalah penjelasan IMO yang sangat singkat, dan saya bertanya-tanya apakah ada yang bisa memberi saya apa gunanya tag ini?
go
reflection
struct
liamzebedee
sumber
sumber
Jawaban:
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 daftarkey:"value"
pasangan yang dipisahkan oleh spasi , misalnya:The
key
biasanya menunjukkan paket yang berikutnya"value"
adalah untuk, misalnyajson
kunci diproses / digunakan olehencoding/json
paket.Jika beberapa informasi dilewatkan dalam
"value"
, biasanya ditentukan dengan memisahkannya dengan koma (','
), misalnyaBiasanya nilai tanda hubung (
'-'
) untuk"value"
sarana untuk mengecualikan bidang dari proses (misalnya dalam kasusjson
itu berarti tidak menyusun atau menghapuskan bidang itu).Contoh mengakses tag khusus Anda menggunakan refleksi
Kita dapat menggunakan refleksi (
reflect
paket) untuk mengakses nilai tag bidang struct. Pada dasarnya kita perlu memperolehType
struct kita, dan kemudian kita dapat query bidang misalnya denganType.Field(i int)
atauType.FieldByName(name string)
. Metode ini mengembalikan nilaiStructField
yang menggambarkan / mewakili bidang struct; danStructField.Tag
merupakan nilai tipeStructTag
yang 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 yangkey
Anda tentukan. The Konvensi diimplementasikan / dibangun ke dalam iniGet()
metode. Jika Anda tidak mengikuti konvensi,Get()
tidak akan dapat menguraikankey:"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 "sepertiGet()
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:
Output (coba di Go Playground ):
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 olehencoding/json
paket, dirinci dijson.Marshal()
xml
- Digunakan olehencoding/xml
paket, dirinci dixml.Marshal()
bson
- Digunakan oleh gobson , dirinci dibson.Marshal()
protobuf
- Digunakan olehgithub.com/golang/protobuf/proto
, dirinci dalam dokumen paketyaml
- Digunakan olehgopkg.in/yaml.v2
paket, dirinci diyaml.Marshal()
db
- digunakan olehgithub.com/jmoiron/sqlx
paket; juga digunakan olehgithub.com/go-gorp/gorp
paketorm
- Digunakan olehgithub.com/astaxie/beego/orm
paket, dirinci di Model - Beego ORMgorm
- digunakan olehgithub.com/jinzhu/gorm
paket, contoh-contoh dapat ditemukan dalam dokumen mereka: Modelvalid
- digunakan olehgithub.com/asaskevich/govalidator
paket, contoh-contoh dapat ditemukan di halaman proyekdatastore
- Digunakan olehappengine/datastore
(platform Google App Engine, layanan Datastore), dirinci di Propertiesschema
- Digunakan olehgithub.com/gorilla/schema
untuk mengisistruct
dengan nilai formulir HTML, dirinci dalam dokumen paketasn
- Digunakan olehencoding/asn1
paket, dirinci diasn1.Marshal()
danasn1.Unmarshal()
csv
- Digunakan olehgithub.com/gocarina/gocsv
paketsumber
Berikut adalah contoh tag yang benar-benar sederhana yang digunakan dengan
encoding/json
paket untuk mengontrol bagaimana bidang ditafsirkan selama penyandian dan penguraian:Coba langsung: http://play.golang.org/p/BMeR8p1cKf
Paket json dapat melihat tag untuk bidang tersebut dan diberi tahu cara memetakan bidang json <=> struct, dan juga opsi tambahan seperti apakah harus mengabaikan bidang kosong saat membuat serial kembali ke json.
Pada dasarnya, paket apa pun dapat menggunakan refleksi pada bidang untuk melihat nilai tag dan bertindak berdasarkan nilai-nilai itu. Ada sedikit lebih banyak info tentang mereka dalam paket refleksi
http://golang.org/pkg/reflect/#StructTag :
sumber
Ini semacam spesifikasi yang menentukan bagaimana paket memperlakukan dengan bidang yang ditandai.
sebagai contoh:
tag json menginformasikan
json
paket yang menyusun output dari pengguna berikutakan seperti ini:
contoh lain adalah
gorm
tag paket menyatakan bagaimana migrasi basis data harus dilakukan:Dalam contoh ini untuk bidang
Email
dengan tag gorm kami menyatakan bahwa kolom yang sesuai dalam basis data untuk email bidang harus bertipe varchar dan panjang maksimum 100 dan juga harus memiliki indeks unik.contoh lain adalah
binding
tag yang digunakan sebagian besar dalamgin
paket.tag yang mengikat dalam contoh ini memberikan petunjuk kepada paket gin bahwa data yang dikirim ke API harus memiliki bidang pengguna dan kata sandi karena bidang ini ditandai seperti yang diperlukan.
Jadi tag umum adalah data yang perlu diketahui paket yang harus diperlakukan dengan data bertipe struct yang berbeda dan cara terbaik untuk membiasakan diri dengan tag yang dibutuhkan paket adalah MEMBACA DOKUMENTASI PAKET SEPENUHNYA.
sumber