Go में टैग के लिए क्या उपयोग हैं?


392

में जाओ भाषा विशिष्टता , यह टैग का एक संक्षिप्त अवलोकन का उल्लेख है:

एक फ़ील्ड घोषणा को वैकल्पिक स्ट्रिंग शाब्दिक टैग द्वारा अनुसरण किया जा सकता है, जो संबंधित फ़ील्ड घोषणा में सभी क्षेत्रों के लिए एक विशेषता बन जाता है। टैग प्रतिबिंब प्रतिबिंब के माध्यम से दिखाई देते हैं, लेकिन अन्यथा नजरअंदाज कर दिए जाते हैं।

// 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, और मैं सोच रहा था कि क्या कोई मुझे ये टैग प्रदान कर सकता है?


मेरे पास 'अर्थ' टिप्पणियों के उपयोग के लिए एक संबंधित प्रश्न है: stackoverflow.com/questions/53101458/…
ब्रूस एडम्स

सुधार है कि लिंक stackoverflow.com/q/53487371/1569204
ब्रूस एडम्स

जवाबों:


641

किसी फ़ील्ड के लिए टैग आपको मेटा-जानकारी को उस फ़ील्ड से जोड़ने की अनुमति देता है जिसे प्रतिबिंब का उपयोग करके प्राप्त किया जा सकता है। आमतौर पर इसका उपयोग ट्रांसफ़ॉर्मेशन जानकारी प्रदान करने के लिए किया जाता है कि कैसे एक संरचनात्मक क्षेत्र को किसी अन्य प्रारूप से (या डेटाबेस से संग्रहीत / पुनर्प्राप्त) से इनकोड किया गया है, लेकिन आप इसका उपयोग उस मेटा-जानकारी को संग्रहीत करने के लिए कर सकते हैं, जिसे आप दूसरे के लिए चाहते हैं। पैकेज या अपने स्वयं के उपयोग के लिए।

के रूप में प्रलेखन में उल्लेख किया गया है 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()(गो 1.7 में जोड़ा गया था) जो "की तरह है, Get()लेकिन टैग को दिए गए टैग से दिए गए कुंजी से अलग नहीं करता है, जो दिए गए कुंजी के साथ एक खाली स्ट्रिंग को जोड़ रहा है"

तो आइए एक सरल उदाहरण देखें:

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

आउटपुट (इसे खेल के मैदान पर आज़माएं ):

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

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

गोफरकेन 2015 में संरचित टैग के बारे में एक प्रस्तुति थी जिसे कहा जाता है:

संरचना टैग (स्लाइड) के कई चेहरे (और एक वीडियो )

यहां आमतौर पर उपयोग की जाने वाली टैग कुंजी की एक सूची दी गई है:

  • json     - encoding/jsonपैकेज द्वारा उपयोग किया जाता है , पर विस्तृतjson.Marshal()
  • xml      - encoding/xmlपैकेज द्वारा उपयोग किया जाता है , पर विस्तृतxml.Marshal()
  • bson     - गोब्सन द्वारा उपयोग किया जाता है , पर विस्तृतbson.Marshal()
  • 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पैकेज द्वारा उपयोग किया जाता है , मॉडल में विस्तृत - बीगो ओआरएम
  • gorm     - github.com/jinzhu/gormपैकेज द्वारा उपयोग किया जाता है , उदाहरण उनके डॉक्टर में पाए जा सकते हैं: मॉडल
  • valid    - github.com/asaskevich/govalidatorपैकेज द्वारा उपयोग किया जाता है , उदाहरण परियोजना पृष्ठ में पाए जा सकते हैं
  • datastore- appengine/datastore(Google ऐप इंजन प्लेटफ़ॉर्म, डेटास्टोर सेवा) द्वारा उपयोग किया जाता है , जो गुणों पर विस्तृत हैं
  • schema   - पैकेज प्रपत्र में विस्तृत HTML फॉर्म वैल्यू के साथ github.com/gorilla/schemaभरने के लिए उपयोग किया जाता हैstruct
  • asn      - encoding/asn1पैकेज द्वारा उपयोग किया जाता है , विस्तृत asn1.Marshal()औरasn1.Unmarshal()
  • csv      - github.com/gocarina/gocsvपैकेज द्वारा उपयोग किया जाता है

28
बहुत बढ़िया जवाब। दस गुना इस कर्म के साथ एक से अधिक उपयोगी जानकारी यहाँ।
डार्थ एलीगस जूल

2
बहुत अच्छा सारांश!
स्टीवनफेरर

2
क्या कमाल का जवाब है
अल्बर्टो मेगिया

1
बहुत बढ़िया जवाब! धन्यवाद!
जम्पअल्स

1
अद्भुत जवाब, इस जानकारी के लिए आप सभी का धन्यवाद!
सैम होम्स

157

यहाँ टैगिंग का वास्तविक उदाहरण encoding/jsonपैकेज के साथ प्रयोग किया जा रहा है ताकि यह नियंत्रित किया जा सके कि एन्कोडिंग और डिकोडिंग के दौरान खेतों की व्याख्या कैसे की जाती है:

लाइव आज़माएं: http://play.golang.org/p/BMeR8p1cKf

package main

import (
    "fmt"
    "encoding/json"
)

type Person struct {
    FirstName  string `json:"first_name"`
    LastName   string `json:"last_name"`
    MiddleName string `json:"middle_name,omitempty"`
}

func main() {
    json_string := `
    {
        "first_name": "John",
        "last_name": "Smith"
    }`

    person := new(Person)
    json.Unmarshal([]byte(json_string), person)
    fmt.Println(person)

    new_json, _ := json.Marshal(person)
    fmt.Printf("%s\n", new_json)
}

// *Output*
// &{John Smith }
// {"first_name":"John","last_name":"Smith"}

Json पैकेज फ़ील्ड के टैग्स को देख सकता है और बताया जा सकता है कि json <=> स्ट्रक्चर फील्ड को मैप कैसे किया जाता है, और अतिरिक्त विकल्प भी हैं जैसे कि json पर वापस जाने पर इसे खाली फ़ील्ड को अनदेखा करना चाहिए या नहीं।

मूल रूप से, कोई भी पैकेज टैग मूल्यों को देखने और उन मूल्यों पर कार्य करने के लिए फ़ील्ड पर प्रतिबिंब का उपयोग कर सकता है। प्रतिबिंबित पैकेज
http://golang.org/pkg/reflect/#StructTag में उनके बारे में थोड़ी और जानकारी है :

कन्वेंशन द्वारा, टैग स्ट्रिंग्स वैकल्पिक रूप से अंतरिक्ष-पृथक कुंजी का एक संयोजन है: "मूल्य" जोड़े। प्रत्येक कुंजी एक गैर-रिक्त स्ट्रिंग है जिसमें अंतरिक्ष (U + 0020 ''), उद्धरण (U + 0022 '"), और बृहदान्त्र (U + 003A': ') के अलावा गैर-नियंत्रण वर्ण होते हैं। प्रत्येक मान उद्धृत किया जाता है। U + 0022 '' अक्षर और गो स्ट्रिंग शाब्दिक वाक्य रचना का उपयोग करना।


6
जावा एनोटेशन की तरह?
इस्माइल बदावी

7
@isbadawi: मैं एक जावा आदमी नहीं हूं, लेकिन जावा एनोटेशन की परिभाषा के त्वरित नज़र में, हाँ ऐसा लगता है कि वे एक ही लक्ष्य प्राप्त कर रहे हैं; मेटाडेटा को उन तत्वों के साथ संलग्न करना जिन्हें रनटाइम पर जांच की जा सकती है।
jd

15
वास्तव में जावा एनोटेशन नहीं। जावा एनोटेशन सुरक्षित और संकलित समय की जाँच कर रहे हैं - जैसे स्ट्रिंग शाब्दिक नहीं। जावा एनोटेशन गोलांग मूल मेटाडेटा प्रावधानों की तुलना में बहुत अधिक शक्तिशाली और मजबूत हैं।
बैठा

2
गो, एमगो के लिए MongoDB ड्राइवर के भाग के रूप में, इसके बॉसन पैकेज में टैग का उपयोग करता है (जिसका उपयोग स्वयं भी किया जा सकता है)। यह आपको BSON के उत्पन्न होने पर सटीक नियंत्रण प्रदान करता है। देखें godoc.org/labix.org/v2/mgo/bson#pkg-files
इनो

1
क्या JSON और BSON के अलावा अन्य उदाहरण हैं?
मैक्स हाइबर

1

यह कुछ प्रकार के विनिर्देश हैं जो निर्दिष्ट करते हैं कि पैकेज किस तरह से टैग किए गए क्षेत्र के साथ व्यवहार करते हैं।

उदाहरण के लिए:

type User struct {
    FirstName string `json:"first_name"`
    LastName string `json:"last_name"`
}

json टैग jsonपैकेज को सूचित करता है कि निम्न उपयोगकर्ता का आउटपुट मार्शल किया गया है

u := User{
        FirstName: "some first name",
        LastName:  "some last name",
    }

इस तरह होगा:

{"first_name":"some first name","last_name":"some last name"}

अन्य उदाहरण है gormपैकेज टैग घोषित करता है कि डेटाबेस का माइग्रेशन कैसे किया जाना चाहिए:

type User struct {
  gorm.Model
  Name         string
  Age          sql.NullInt64
  Birthday     *time.Time
  Email        string  `gorm:"type:varchar(100);unique_index"`
  Role         string  `gorm:"size:255"` // set field size to 255
  MemberNumber *string `gorm:"unique;not null"` // set member number to unique and not null
  Num          int     `gorm:"AUTO_INCREMENT"` // set num to auto incrementable
  Address      string  `gorm:"index:addr"` // create index with name `addr` for address
  IgnoreMe     int     `gorm:"-"` // ignore this field
}

इस उदाहरण में Emailgorm टैग के साथ फ़ील्ड के लिए हम यह घोषित करते हैं कि फ़ील्ड ईमेल के लिए डेटाबेस में संबंधित कॉलम प्रकार varchar और 100 अधिकतम लंबाई का होना चाहिए और इसमें विशिष्ट अनुक्रमणिका भी होनी चाहिए।

अन्य उदाहरण वे bindingटैग हैं जो अधिकतर ginपैकेज में उपयोग किए जाते हैं ।

type Login struct {
    User     string `form:"user" json:"user" xml:"user"  binding:"required"`
    Password string `form:"password" json:"password" xml:"password" binding:"required"`
}


var json Login
if err := c.ShouldBindJSON(&json); err != nil {
     c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
     return
}

इस उदाहरण में बाइंडिंग टैग जिन पैकेज को संकेत देता है कि एपीआई को भेजे गए डेटा में उपयोगकर्ता और पासवर्ड फ़ील्ड होना चाहिए, क्योंकि ये फ़ील्ड आवश्यकतानुसार टैग किए गए हैं।

तो जनरली टैग डेटा होते हैं जिन्हें पैकेज को यह जानना आवश्यक होता है कि उन्हें विभिन्न प्रकार के डेटा के साथ कैसा व्यवहार करना चाहिए और पैकेज की ज़रूरत के अनुसार टैग से परिचित होने का सबसे अच्छा तरीका क्या है, एक पैकेज डेटा संकलन की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.