2013-12-09 9 views
15

json.Unmarshal डॉक्स (सादगी []Animal के बजाय Animal का उपयोग करने के लिए थोड़ा संशोधित) से इस उदाहरण से काम करता है, कोई त्रुटि:json.Unmarshal संदर्भ के साथ क्यों काम करता है लेकिन पॉइंटर नहीं?

Playground link of working example

// ... 
var animals Animal 
err := json.Unmarshal(jsonBlob, &animals) 
// ... 

लेकिन यह थोड़ा संशोधित उदाहरण नहीं करता है:

Playground link of non-working example

// ... 
var animals *Animal 
err := json.Unmarshal(jsonBlob, animals) 
// ... 

json: unmarshal (शून्य * main.Animal)

यह प्रतीत होता हैयह इस अस्पष्ट त्रुटि है कि वास्तव में सहायक (अधिक एक त्रुटि IMO की तुलना में एक समारोह कॉल की तरह दिखता है) नहीं है को प्रदर्शित करता है क्योंकि animals एक प्रारंभिक सूचक है। लेकिन दस्तावेज़ कहते हैं (जोर मेरा):

उमरशाल जेएसओएन को पॉइंटर द्वारा इंगित मूल्य में अनारशल करता है। यदि पॉइंटर शून्य है, तो Unmarshal इसके लिए इंगित करने के लिए एक नया मान आवंटित करता है।

तो क्यों दूसरे उदाहरण में अशांति विफल हो रही है और अस्पष्ट त्रुटि दिखाती है?

उत्तर

18

आप एक का सामना करना पड़ा InvalidUnmarshalError (देखें lines 109 and 110 in decode.go)।

// एक अवैध UnnmarshalError Unmarshal को पारित एक अवैध तर्क का वर्णन करता है।
// (unmarshal को तर्क एक गैर शून्य सूचक होना चाहिए।)

ऐसा लगता है डॉक्स उपर्युक्त उद्धरण और from the Unmarshal source नीचे टिप्पणी के रूप में कुछ स्पष्टीकरण के साथ कर सकता एक दूसरे को खंडन करने के लिए लग रहे हैं।

यदि सूचक शून्य है, तो Unmarshal इसके लिए एक नया मान आवंटित करता है।

13

क्योंकि आपके सूचक नहीं के बराबर है (इसके अलावा, यह "unmarshalling" या "unmarshaling" (एक एल)? डॉक्स दोनों का उपयोग करें। है)।

आप इसे प्रारंभ यदि यह काम करता है: http://play.golang.org/p/zprmV0O1fG

var animals *Animal = &Animal{} 

इसके अलावा, यह किसी भी तरह से वर्तनी जा सकता है (एक ही दस्तावेज़ में स्थिरता अच्छा होगा, हालांकि): http://en.wikipedia.org/wiki/Marshalling_(computer_science)

+0

ठीक है, लेकिन फिर उमरशाल के लिए प्रलेखन में इसका क्या अर्थ है: "यदि सूचक शून्य है, तो अनमारशल इसके लिए एक नया मान आवंटित करता है।" अगर उमरशाल हमारे लिए ऐसा कर रहा है तो हमें इसे क्यों शुरू करना होगा? – Matt

+0

हाहा, हाँ मैंने अभी आपके प्रश्न में देखा है। खैर, यदि आप सूचक के संदर्भ में पास करते हैं, तो यह भी आवंटित करता है। http://play.golang.org/p/3KP7pPKmBp –

+0

दिलचस्प। तो क्या मेरी समझ है कि "पॉइंटर" का अर्थ गलत है या क्या दस्तावेज़ गलत हैं? क्योंकि मैं यहां काम करने वाले सभी संदर्भ संदर्भ हैं, पॉइंटर्स नहीं। – Matt

-1

मुझे पहले एक समान स्थिति थी लेकिन एक अलग मामले में। यह गो में इंटरफ़ेस की अवधारणा से संबंधित है। एक समारोह तर्क या वापसी मान, के रूप में एक अंतरफलक वाणी तो फोन करने वाले पास या संदर्भ लौट

आपके मामले में करने के लिए है, json.Unmarshal दूसरा तर्क के रूप में इंटरफ़ेस को स्वीकार

5

मेरा मानना ​​है कि मुद्दा यह है कि, जबकि आप पॉइंटर को से Unmarshal() तक पास कर सकते हैं, आप शून्य पॉइंटर मान पास नहीं कर सकते हैं।

नहीं के बराबर करने के लिए एक सूचक होगा जैसे: v का मूल्य

var v interface{} 
json.Unmarshal(text, &v) 

नहीं के बराबर है, लेकिन v सूचक एक गैर शून्य सूचक पता है। यह एक गैर-शून्य सूचक है, जो एक शून्य इंटरफ़ेस को इंगित कर रहा है {} (जो स्वयं एक सूचक प्रकार है)। Unmarshal इस मामले में एक त्रुटि वापस नहीं करता है।

एक शून्य सूचक होगा जैसे:

var v *interface{} 
json.Unmarshal(text, v) 

इस मामले में, वी के प्रकार pointer to an interface{} है, लेकिन golang में एक वर के किसी भी घोषणा के साथ के रूप में, v का प्रारंभिक मूल्य प्रकार का शून्य है मूल्य। तो v एक शून्य-मूल्य सूचक है, जिसका अर्थ यह है कि यह स्मृति में किसी भी वैध स्थान को इंगित नहीं कर रहा है।

https://stackoverflow.com/a/20478917/387176 में उल्लेख किया है, json.Unmarshal() कुछ के लिए एक वैध सूचक की जरूरत है, तो यह कुछ बदल सकते हैं जगह में (यह एक शून्य मान struct, या एक सूचक हो)।

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