2015-04-21 6 views
5

मैं एक स्ट्रक्चर के एन्कोडिंग प्रारूप को कस्टमाइज़ करना चाहता हूं लेकिन त्रुटि मिली: जेसन: मार्शल जेसन को टाइप करने के लिए त्रुटि मुख्य। इंफो: अवैध अक्षर 'ओ' शाब्दिक झूठी ('ए' की उम्मीद) मेरे कोड में क्या गलत है?गो में JSON एन्कोडिंग आउटपुट को कैसे अनुकूलित करें?

package main 

import (
    "bytes" 
    "encoding/json" 
    "fmt" 
    "log" 
) 

type Info struct { 
    name string 
    flag bool 
} 

func (i Info) MarshalJSON() ([]byte, error) { 
    var b bytes.Buffer 
    b.Write([]byte(i.name)) 
    if i.flag { 
     b.Write([]byte(`"true"`)) 
    } else { 
     b.Write([]byte(`"false"`)) 
    } 
    return b.Bytes(), nil 
} 

func main() { 
    a := []Info{ 
     {"foo", true}, 
     {"bar", false}, 
    } 
    out, err := json.Marshal(a) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Printf(string(out)) 
} 

उत्तर

0

एक बफर करने के लिए अपने स्वयं के तार लेखन तरह का json.Marshal() के प्रयोजन के समाप्त करता है। हो सकता है कि कुछ इस तरह:

type Info struct { 
    Name string `json:"name"` // Struct fields should have capital first letter 
           // if you want it to be found by the marshaller. 
    Flag bool `json:"flag"` // json:"flag" assigns the object key in json format 
} 

और फिर कुछ की तरह:

myInfo := Info { 
    Name: "Foo", 
    Flag: true, 
} 
slc, _ := json.Marshal(myInfo) 
fmt.Println(string(slc)) 
2

आपका कोड अमान्य JSON टेक्स्ट पैदा करता है।

तुम भी क्षेत्रों के नाम लिखना चाहिए, और सुरक्षा बोली दोनों फ़ील्ड का नाम और string मूल्यों लेकिनbool मूल्यों बोली नहीं है के लिए (और जाना json पैकेज यह bool में उदाहरण के लिए unmarshal नहीं होगा)। इसके अलावा कोष्ठक {} इस तरह में अपने मूल्यों संलग्न:

b.Write([]byte(`{"name":"`))  // started with { 
b.Write([]byte(i.name)) 
b.Write([]byte(`","flag":`))  // note the , between values 
if i.flag { 
    b.Write([]byte(`true`))  // don't quote boolean value 
} else { 
    b.Write([]byte(`false`))  // don't quote boolean value 
} 
b.Write([]byte(`}`))    // must close with } 

आउटपुट (Go Playground पर पूरा आवेदन की कोशिश):

[{"name":"foo","flag":true},{"name":"bar","flag":false}] 

लेकिन जब से तुम कुछ भी विशेष मार्शल के दौरान नहीं कर रहे हैं, बस खेतों को निर्यात करें (उन्हें ऊपरी-केस अक्षरों से शुरू करके) और json पैकेज स्वचालित रूप से आपके लिए मार्शल/अनमशाल होगा:

type Info struct { 
    Name string 
    Flag bool 
} 

इस संस्करण को Go Playground पर आज़माएं।

आउटपुट (ध्यान दें ऊपरी मामलों नाम "Name" और "Flag"):

type Info struct { 
    Name string `json:"name"` 
    Flag bool `json:"flag"` 
} 
:

[{"Name":"foo","Flag":true},{"Name":"bar","Flag":false}] 

तुम भी आप इस तरह JSON टेक्स्ट में अलग-अलग नामों उपयोग करना चाहते हैं टैग का उपयोग कर सकते हैं

यह फिर से कम-आधारित नामों के साथ आउटपुट उत्पन्न करेगा:

[{"name":"foo","flag":true},{"name":"bar","flag":false}] 

json.Marshal() फ़ंक्शन के दस्तावेज़ को पढ़ें ताकि आप यह देखने के लिए कि कौन से विकल्प और अनुकूलन आप संरचना टैग के साथ कर सकते हैं।

+0

ओह, मैंने सोचा है कि मैं मार्शल को जो कुछ भी चाहता हूं वह अवैध जेएसओएन पाठ – Meng

+1

@Meng जिसे JSON मार्शलिंग कहा जाता है, जिसे _any_ बाइनरी/टेक्स्ट सामग्री उत्पन्न कहा जाता है। – icza

0

समस्या यह है कि आप MarshalJSON के कार्यान्वयन के भीतर आपके लिए जादुई रूप से बहुत कुछ होने की उम्मीद कर रहे हैं। दुर्भाग्य से आपको इसे देखने की ज़रूरत है जैसे कि आप स्ट्रिंग को पूरी तरह से स्क्रैच से बना रहे हैं। इसका मतलब है;

func (i Info) MarshalJSON() ([]byte, error) { 
    var b bytes.Buffer 
    b.Write([]byte(i.name)) 
    if i.flag { 
     b.Write([]byte(`"true"`)) 
    } else { 
     b.Write([]byte(`"false"`)) 
    } 
    return b.Bytes(), nil 
} 

इस तरह दिखने की आवश्यकता है;

func (i Info) MarshalJSON() ([]byte, error) { 
    var b bytes.Buffer 
    b.Write([]byte(`{"name":"`))  
    b.Write([]byte(i.name)) 
    b.Write([]byte(`","flag":`))   
    if i.flag { 
     b.Write([]byte(`"true"`))   
    } else { 
     b.Write([]byte(`"false"`))  
    } 
    b.Write([]byte(`}`)) 
} 

इसके अलावा, मैं आप वैध तरीके से बूलियन मूल्यों के लिए एक स्ट्रिंग चाहते संभालने कर रहा हूँ (अन्यथा क्यों इस विधि बिल्कुल सही लागू,?), यदि नहीं तो आप अगर से छुटकारा पाना चाहते हैं और बस b.Write([]byte(i.flag)) का उपयोग करना चाहते हैं।

संबंधित मुद्दे