2012-06-20 12 views
40

क्या कोई तकनीकी कारण है कि अनावृत फ़ील्ड एन्कोडिंग/जेसन द्वारा क्यों शामिल नहीं हैं? यदि नहीं है और यह एक मनमाने ढंग से निर्णय है, तो एक अतिरिक्त बैक दरवाजा विकल्प ('+' कहें) जिसमें अप्रत्याशित हालांकि शामिल हो सकता है?JSON और बिना निर्यात किए गए फ़ील्ड से निपटना

इस कार्यक्षमता को प्राप्त करने के लिए निर्यात करने के लिए क्लाइंट कोड की आवश्यकता दुर्भाग्यपूर्ण लगती है, खासकर अगर निचला मामला encapsulation प्रदान कर रहा है या मार्शल संरचनाओं का निर्णय उनके डिजाइन के बाद बहुत बाद में आता है।

लोग इस से कैसे निपट रहे हैं? बस सबकुछ निर्यात करें?

इसके अलावा, फ़ील्ड नामों का निर्यात नहीं करना सुझाया गया मुहावरों का पालन करना मुश्किल बनाता है। मुझे लगता है कि यदि एक स्ट्रक्चर एक्स में फ़ील्ड वाई है, तो आपके पास एक्सेसर विधि वाई() नहीं हो सकती है। यदि आप वाई को इंटरफ़ेस पहुंच प्रदान करना चाहते हैं तो आपको गेटटर के लिए एक नया नाम आना होगा और इससे कोई फर्क नहीं पड़ता कि आपको http://golang.org/doc/effective_go.html#Getters

उत्तर

64

के अनुसार कोई गैर-मूर्खतापूर्ण कुछ नहीं मिलेगा। तकनीकी कारण है। जेसन लाइब्रेरी में फ़ील्ड को तब तक देखने की शक्ति नहीं है जब तक उन्हें निर्यात नहीं किया जाता है। एक पैकेज केवल अपने पैकेज के भीतर अनपेक्षित फ़ील्ड प्रकारों को देख सकता है

अपनी समस्या से निपटने के लिए, आप क्या कर सकते हैं निर्यात किए गए फ़ील्ड के साथ एक अप्रत्याशित प्रकार बना सकते हैं। बिना किसी समस्या के पारित होने पर जेसन एक अप्रत्याशित प्रकार में अनमर्शल होगा लेकिन यह एपीआई दस्तावेज़ों में दिखाई नहीं देगा। फिर आप निर्यात किए गए प्रकार को बना सकते हैं जो अप्रत्याशित प्रकार को एम्बेड करता है। इस निर्यात किए गए प्रकार को json.Marshaler और json.Unmarshaler इंटरफेस को लागू करने के तरीकों की आवश्यकता होगी।

नोट: सभी कोड अनचाहे हैं और यहां तक ​​कि संकलित भी नहीं हो सकते हैं।

type jsonData struct { 
    Field1 string 
    Field2 string 
} 

type JsonData struct { 
    jsonData 
} 

// Implement json.Unmarshaller 
func (d *JsonData) UnmarshalJSON(b []byte) error { 
    return json.Unmarshal(b, &d.jsonData) 
} 

// Getter 
func (d *JsonData) Field1() string { 
    return d.jsonData.Field1 
} 
+0

रिकॉर्ड के लिए, मुझे "json.Unmarshal (b, और d.jsonData)" का उपयोग करके Unmarshall करना पड़ा। क्या मैंने कुछ गलत किया, या उम्मीद है? – Derek

+0

@ डेरेक, धन्यवाद, मैंने अपना जवाब अपडेट किया। जैसा कि मैंने कहा था कि कोड अवांछित था। मैं भी स्पष्ट रूप से अपने 'UnmarshalJSON()' विधि में एक वापसी बयान भूल गया। मैंने इसे भी ठीक किया। –

+3

मैं शो के लिए थोड़ा देर हो चुकी हूं, लेकिन ... उपरोक्त कार्यों के दौरान, फील्ड 1 और फ़ील्ड 2 _are_ निर्यात किया गया। आप उस पैकेज के बाहर जेसनडाटा (पूंजी जे के साथ) के फील्ड 1 और फील्ड 2 को पढ़ और लिख सकते हैं। इसलिए, यह सिद्धांत में ठंडा है, लेकिन यह वास्तव में प्रकार और फ़ील्ड दोनों को निर्यात करने से अलग कुछ नहीं करता है। – davidjosepha

41

स्टीफन का उत्तर पूरा हो गया है। एक अलग रूप में के रूप में, अगर सब तुम सच में चाहते हैं कि आपके json में लोअरकेस कुंजी है, तो आप मैन्युअल कुंजी नाम इस प्रकार निर्दिष्ट कर सकते हैं:

type Whatever struct { 
    SomeField int `json:"some_field"` 
} 

कि रास्ते में, प्रमुखता एक जो कुछ भी क्षेत्र SomeField के लिए कुंजी "some_field" का उत्पादन (आपके जेसन में "कुछ फ़ील्ड" होने के बजाय)।

यदि आप अप्रत्याशित फ़ील्ड रखने पर मृत-सेट हैं, तो आप json.Marshaler इंटरफेस को हस्ताक्षर MarshalJSON() ([]byte, error) के साथ विधि को परिभाषित करके भी कार्यान्वित कर सकते हैं।

type Whatever struct { 
    someField int 
} 

func (w Whatever) MarshalJSON() ([]byte, error) { 
    return json.Marshal(struct{ 
     SomeField int `json:"some_field"` 
    }{ 
     SomeField: w.someField, 
    }) 
} 

कि थोड़ा बोझिल हो सकता है, तो आप भी एक map[string]interface{} यदि आप पसंद का उपयोग कर सकते हैं::

एक तरीका यह करने के लिए एक struct शाब्दिक कि बस इस तरह, unexported क्षेत्रों के संस्करणों का निर्यात किया है उपयोग करने के लिए है
func (w Whatever) MarshalJSON() ([]byte, error) { 
    return json.Marshal(map[string]interface{}{ 
     "some_field": w.SomeField, 
    }) 
} 

हालांकि यह ध्यान दिया जाना चाहिए कि प्रमुखता interface{} कुछ चेतावनियां है और एक नाव के लिए मार्शल uint64 जैसे काम कर सकें, सटीक का नुकसान के कारण। (सभी कोड untested)

+0

तकनीकी रूप से, जावास्क्रिप्ट में सभी संख्याएं फ़्लोट हैं। –

+16

JSON जावास्क्रिप्ट नहीं है। जेएसओएन स्पेक केवल बताता है कि कौन से पात्र स्वीकार्य हैं, न कि संख्यात्मक श्रेणियां मान्य हैं। 876234958273645982736459827346598237465923847561203947812435968234659827346 जैसी संख्या अभी भी JSON में मान्य है, भले ही इसे जावास्क्रिप्ट द्वारा समझा जा सके। वास्तविक दुनिया के उदाहरण के लिए, ट्विटर एपीआई ट्वीट आईडी को 64 बिट हस्ताक्षरित पूर्णांक के रूप में दर्शाती है, जो जावास्क्रिप्ट में मान्य नहीं है, लेकिन वैध JSON है। – jorelli

+1

वर्तमान में, सभी सत्य, लेकिन फिर भी नाम JSON है, जो ऐतिहासिक रूप से "जावास्क्रिप्ट ऑब्जेक्ट नोटेशन" के लिए खड़ा है। उन छोटे आश्चर्यजनक बिट्स में से एक जो आप इसे एनजेएसओएन (न्यूजसन या नॉटजवास्क्रिप्ट) में बदलना चाहते हैं :) – quetzalcoatl

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