1. encoding/json
मानक पुस्तकालय का अवलोकन
Go भाषा encoding/json
पुस्तकालय प्रदान करती है जो JSON डेटा प्रारूप को संभालने के लिए शक्तिशाली है। इस पुस्तकालय के साथ, आप आसानी से Go डेटा प्रकार को JSON प्रारूप में परिवर्तित कर सकते हैं (सिरणीकरण) या JSON डेटा को Go डेटा प्रकारों में परिवर्तित कर सकते हैं (असिरणीकरण)। यह पुस्तकालय कई कार्यों जैसे कोडित, डिकोडित, स्ट्रीमिंग आईओ, और कस्टम JSON विश्लेषण तर्क का समर्थन प्रदान करती है।
इस पुस्तकालय में सबसे महत्वपूर्ण डेटा प्रकार और फ़ंक्शन शामिल हैं:
-
Marshal
औरMarshalIndent
: Go डेटा प्रकारों को JSON स्ट्रिंग में सिरणीकरण के लिए प्रयोग किया जाता है। -
Unmarshal
: JSON स्ट्रिंग को Go डेटा प्रकारों में असिरणीकरण के लिए प्रयोग किया जाता है। -
Encoder
औरDecoder
: JSON डेटा की स्ट्रीमिंग आईओ के लिए प्रयोग किया जाता है। -
Valid
: दिया गया स्ट्रिंग यदि वैध JSON प्रारूप है तो प्रयोग किया जाता है।
हम आगामी अध्यायों में इन फ़ंक्शनों और प्रकारों के उपयोग को विशेष रूप से सीखेंगे।
2. Go डेटा संरचनाओं को JSON में सिरणीकरण
2.1 json.Marshal
का प्रयोग
json.Marshal
एक फ़ंक्शन है जो Go डेटा प्रकारों को JSON स्ट्रिंग में सिरणीकरण करता है। यह Go भाषा से डेटा प्रकारों को इनपुट के रूप में लेता है, उन्हें JSON प्रारूप में परिवर्तित करता है, और एक बाइट स्लाइस के साथ संभावित त्रुटियों के साथ लौटाता है।
यहां एक सरल उदाहरण है जो एक Go स्ट्रक्ट को JSON स्ट्रिंग में कैसे परिवर्तित करता है:
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
person := Person{"Alice", 30}
jsonData, err := json.Marshal(person)
if err != nil {
log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Println(string(jsonData)) // Output: {"name":"Alice","age":30}
}
स्ट्रक्ट के अलावा, json.Marshal
फ़ंक्शन मैप और स्लाइस जैसे अन्य डेटा प्रकारों को सिरणीकरण कर सकता है। नीचे map[string]interface{}
और slice
का प्रयोग करके उदाहरण है:
// मैप को JSON में परिवर्तित करें
myMap := map[string]interface{}{
"name": "Bob",
"age": 25,
}
jsonData, err := json.Marshal(myMap)
// ... त्रुटि हैंडलिंग और आउटपुट छूट दिया गया ...
// स्लाइस को JSON में परिवर्तित करें
mySlice := []string{"Apple", "Banana", "Cherry"}
jsonData, err := json.Marshal(mySlice)
// ... त्रुटि हैंडलिंग और आउटपुट छूट दिया गया ...
2.2 स्ट्रक्ट टैग
Go में, स्ट्रक्ट टैग का उपयोग स्ट्रक्ट फ़ील्ड्स के लिए मेटाडेटा प्रदान करने के लिए किया जाता है, जो JSON सीरियलाइज़ेशन के व्यवहार को नियंत्रित करता है। सबसे सामान्य उपयोग मामले में फ़ील्ड का नाम बदलना, फ़ील्डों को अनदेखा करना, और शर्तबद्ध सीरियलाइज़ेशन शामिल हैं।
उदाहरण के लिए, आप टैग json:"<नाम>"
का प्रयोग करके JSON फ़ील्ड का नाम निर्दिष्ट कर सकते हैं:
type Animal struct {
SpeciesName string `json:"species"`
Description string `json:"desc,omitempty"`
Tag string `json:"-"` // "-" टैग जोड़ने से इस फ़ील्ड का अर्थ है कि इसे सीरियलाइज़ नहीं किया जाएगा
}
ऊपर के उदाहरण में, Tag
फ़ील्ड के सामने json:"-"
टैग json.Marshal
को बताता है कि इस फ़ील्ड को अनदेखा करना है। Description
फ़ील्ड के लिए omitempty
विकल्प यह दर्शाता है कि यदि फ़ील्ड खाली है (शून्य मान, जैसे रिक्त स्ट्रिंग), तो इसे सिरियलाइज़ किया नहीं जाएगा।
यहां स्ट्रक्ट टैग का प्रयोग करके एक पूरा उदाहरण है:
package main
import (
"encoding/json"
"fmt"
"log"
)
type Animal struct {
SpeciesName string `json:"species"`
Description string `json:"desc,omitempty"`
Tag string `json:"-"`
}
func main() {
animal := Animal{
SpeciesName: "African Elephant",
Description: "A large mammal with a trunk and tusks.",
Tag: "endangered", // इस फ़ील्ड को JSON में सीरियलाइज़ नहीं किया जाएगा
}
jsonData, err := json.Marshal(animal)
if err != nil {
log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Println(string(jsonData)) // आउटपुट: {"species":"African Elephant","desc":"A large mammal with a trunk and tusks."}
}
इस तरह, आप सुनिश्चित कर सकते हैं कि JSON प्रस्तुति को नियंत्रित करते हुए स्पष्ट डेटा संरचना सुनिश्चित कर सकते हैं, विभिन्न सीरियलाइज़ेशन आवश्यकताओं को लचीलापूर्वक संभाल सकते हैं।
3. JSON को Go डेटा संरचना में असिरणीकरण
3.1 json.Unmarshal
का उपयोग
json.Unmarshal
फ़ंक्शन हमें JSON स्ट्रिंग को गो डेटा संरचनाओं जैसे कि स्ट्रक्चर, मैप आदि में पार्स करने की अनुमति देता है। json.Unmarshal
का उपयोग करने के लिए, हमें पहले एक ऐसा गो डेटा संरचना परिभाषित करनी होती है जो JSON डेटा से मेल खाती हो।
मान लें हमारे पास निम्नलिखित JSON डेटा है:
{
"name": "Alice",
"age": 25,
"emails": ["[email protected]", "[email protected]"]
}
इस डेटा को गो स्ट्रक्चर में पार्स करने के लिए, हमें एक मिलता-जुलता स्ट्रक्चर परिभाषित करना होगा:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Emails []string `json:"emails"`
}
अब हम डिसीरियलाइज़ेशन के लिए json.Unmarshal
का उपयोग कर सकते हैं:
import (
"encoding/json"
"fmt"
)
func main() {
jsonData := `{
"name": "Alice",
"age": 25,
"emails": ["[email protected]", "[email protected]"]
}`
var user User
err := json.Unmarshal([]byte(jsonData), &user)
if err != nil {
fmt.Println("JSON का डिसीरियलाइज़ेशन में त्रुटि:", err)
return
}
fmt.Printf("User: %+v\n", user)
}
ऊपर के उदाहरण में, हमने json:"name"
जैसे टैग का उपयोग करके json.Unmarshal
फ़ंक्शन को JSON फ़ील्ड को स्ट्रक्चर फ़ील्ड के साथ मैप करने के बारे में सूचित किया।
4.2 JSON Arrays
JSON में, arrays एक सामान्य डेटा संरचना हैं। Go में, ये slices के समान होते हैं।
नीचे दिए गए JSON array को ध्यान से देखें:
[
{"name": "Dave", "age": 34},
{"name": "Eve", "age": 28}
]
Go में, हम निम्नलिखित struct और slice को निर्धारित करते हैं:
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
jsonData := `[
{"name": "Dave", "age": 34},
{"name": "Eve", "age": 28}
]`
var people []Person
json.Unmarshal([]byte(jsonData), &people)
for _, person := range people {
fmt.Printf("%+v\n", person)
}
}
इस तरह, हम JSON array में प्रत्येक तत्व को Go structs के slice में deserialize कर सकते हैं जिससे आगे की प्रक्रिया और पहुंच संभव होती है।
5 त्रुटि संसाधन
JSON डेटा के साथ संबंधित होते समय, चाहे वह serialization (संरचित डेटा को JSON प्रारूप में बदलना) हो या deserialization (JSON को वापस संरचित डेटा में बदलना) हो, त्रुटियाँ हो सकती हैं। आगे, हम सामान्य त्रुटियों और उन्हें संभालने के तरीकों पर चर्चा करेंगे।
5.1 सीरियलाइज़ेशन त्रुटि संसाधन
सीरियलाइज़ेशन त्रुटियाँ सामान्य रूप से एक struct या अन्य डेटा प्रकार को एक JSON स्ट्रिंग में बदलने की प्रक्रिया के दौरान होती हैं। उदाहरण के लिए, अगर किसी struct में गैर कानूनी फील्ड (जैसे एक चैनल प्रकार या फ़ंक्शन) को serialize करने का प्रयास किया जाता है, तो json.Marshal
में एक त्रुटि वापस करेगा।
import (
"encoding/json"
"fmt"
"log"
)
type User struct {
Name string
Age int
// मान लें यहां एक फ़ील्ड है जो सीरियलाइज़ किया नहीं जा सकता
// Data chan struct{} // चैनल्स को JSON में प्रस्तुत नहीं किया जा सकता
}
func main() {
u := User{
Name: "Alice",
Age: 30,
// Data: make(chan struct{}),
}
bytes, err := json.Marshal(u)
if err != nil {
log.Fatalf("JSON serialization failed: %v", err)
}
fmt.Println(string(bytes))
}
उपरोक्त उदाहरण में, हमने जानबूझकर Data
फ़ील्ड को टिप्पणी कर दी है। अगर टिप्पणी हटाई जाती है, तो सीरियलाइज़ेशन विफल होगा, और प्रोग्राम त्रुटि को लॉग करेगा और क्रियान्वयन को समाप्त करेगा। इस प्रकार की त्रुटियों को संभालने में सामान्य रूप से त्रुटियों की जाँच करना और संबंधित त्रुटि संसाधन रणनीतियों (जैसे त्रुटियों को लॉग करना, डिफ़ॉल्ट डेटा वापसी करना, आदि) का अमल करना होता है।
5.2 डीसीरियलाइज़ेशन त्रुटि संसाधन
डीसीरियलाइज़ेशन त्रुटियाँ जब हो सकती हैं, जब JSON स्ट्रिंग को वापस Go struct या अन्य डेटा प्रकार में बदला जाता है। उदाहरण के लिए, अगर JSON स्ट्रिंग प्रारूप गलत हो या लक्ष्य प्रकार के साथ असंगत हो, तो json.Unmarshal
एक त्रुटि वापस करेगा।
import (
"encoding/json"
"fmt"
"log"
)
func main() {
var data = []byte(`{"name":"Alice","age":"unknown"}`) // "age" को एक पूर्णांक होना चाहिए, लेकिन यहां एक स्ट्रिंग प्रदान की गई है
var u User
err := json.Unmarshal(data, &u)
if err != nil {
log.Fatalf("JSON deserialization failed: %v", err)
}
fmt.Printf("%+v\n", u)
}
इस कोड उदाहरण में, हमने जानबूझकर age
फ़ील्ड के लिए गलत डेटा प्रकार प्रदान किया है (पूर्णांक की बजाय एक स्ट्रिंग), जिससे json.Unmarshal
एक त्रुटि फेंकेगा। इसलिए, हमें इस स्थिति का सामान्य तरीके से संभालने की आवश्यकता है। सामान्य अभ्यास है कि हम त्रुटि संदेश को लॉग करें और स्थिति के आधार पर संभावना के हिसाब से एक खाली ऑब्जेक्ट, डिफ़ॉल्ट मान या त्रुटि संदेश वापसी करें।
6 उन्नत सुविधाएँ और प्रदर्शन अनुकूलन
6.1 कस्टम मार्शल और अनमार्शल
गो में, डिफ़ॉल्ट रूप से encoding/json
पैकेज JSON को reflection के माध्यम से serialize और deserialize करता है। हालांकि, हम json.Marshaler
और json.Unmarshaler
इंटरफेस को लागू करके इन प्रक्रियाओं को अनुकूलित कर सकते हैं।
import (
"encoding/json"
"fmt"
)
type Color struct {
Red uint8
Green uint8
Blue uint8
}
func (c Color) MarshalJSON() ([]byte, error) {
hex := fmt.Sprintf("\"#%02x%02x%02x\"", c.Red, c.Green, c.Blue)
return []byte(hex), nil
}
func (c *Color) UnmarshalJSON(data []byte) error {
_, err := fmt.Sscanf(string(data), "\"#%02x%02x%02x\"", &c.Red, &c.Green, &c.Blue)
return err
}
func main() {
c := Color{Red: 255, Green: 99, Blue: 71}
jsonColor, _ := json.Marshal(c)
fmt.Println(string(jsonColor))
var newColor Color
json.Unmarshal(jsonColor, &newColor)
fmt.Println(newColor)
}
यहां, हमने Color
टाइप को परिभाषित किया है और MarshalJSON
और UnmarshalJSON
मेथड्स को संख्यात्मक रूप में रंगों को हेक्साडेसिमल स्ट्रिंग में और फिर से रंगों को एरजीबी में कन्वर्ट करने के लिए अंमल किया है।
6.2 इनकोडर्स और डीकोडर्स
जब भीड़ JSON डेटा के साथ काम करते हैं, json.Marshal
और json.Unmarshal
का सीधा उपयोग अधिक मेमोरी उपभोग या अपर्याप्त इनपुट/आउटपुट प्रक्रियाओं की ओर ले जा सकता है। इसलिए, गो में encoding/json
पैकेज द्वारा Encoder
और Decoder
टाइप्स प्रदान किए गए हैं, जो JSON डेटा को स्ट्रीमिंग तरीके से प्रसंस्करण कर सकते हैं।
6.2.1 json.Encoder
का उपयोग
json.Encoder
सीधे वहाँ JSON डेटा को किसी भी ऑब्जेक्ट में लिख सकता है जो io.Writer इंटरफेस को अनुकरण करता है, जिससे आप JSON डेटा को सीधे फ़ाइल, नेटवर्क कनेक्शन, आदि में एनकोड कर सकते हैं।
import (
"encoding/json"
"os"
)
func main() {
users := []User{
{Name: "Alice", Age: 30},
{Name: "Bob", Age: 25},
}
file, _ := os.Create("users.json")
defer file.Close()
encoder := json.NewEncoder(file)
if err := encoder.Encode(users); err != nil {
log.Fatalf("Encoding error: %v", err)
}
}
6.2.2 json.Decoder
का उपयोग
json.Decoder
सीधे वहाँ JSON डेटा को किसी भी ऑब्जेक्ट में डेड कर सकता है जो io.Reader इंटरफेस को अनुकरण करता है, जांचता है और JSON ऑब्ज