2016-08-23 4 views
12

को देखते हुए निम्नलिखित कोड: त्रुटि के लिएगो में, क्या एक अच्छी तरह से परिभाषित प्रकार की जेएसओएन मार्शलिंग कभी विफल हो सकती है?

package main 

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

type Employee struct { 
    Id int "json:id" 
} 

func main() { 
    b, err := json.Marshal(&Employee{Id: 2}) 
    if err != nil { 
     log.Fatal("Couldn't marshal the Employee") 
    } 

    fmt.Println(string(b)) 
} 

Can जाँच मज़बूती के बाद से Employee struct अच्छी तरह से परिभाषित किया गया है _ प्लेसहोल्डर का उपयोग कर नजरअंदाज कर दिया। सैद्धांतिक रूप से यह कभी असफल नहीं होना चाहिए, इसलिए प्रश्न पूछता है कि इस प्रकार की त्रुटि को अनदेखा करना और इस प्रकार के बॉयलरप्लेट त्रुटि जांच पर थोड़ा सा बचाएं?

की उपेक्षा तो ऐसा दिखाई देगा:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Employee struct { 
    Id int "json:id" 
} 

func main() { 
    b, _ := json.Marshal(&Employee{Id: 2}) 
    fmt.Println(string(b)) 
} 
+7

अच्छा, आमतौर पर यह असफल नहीं होगा। कर्मचारी कुछ भी नहीं है जो गलत हो सकता है। लेकिन कोई कभी नहीं जानता, विशेष रूप से जैसे structs बढ़ने लगते हैं लेकिन कोई भी मार्शलिंग की जांच नहीं करेगा। एक फ़ील्ड 'बॉस * कर्मचारी' जोड़ें, एक बग के साथ गठबंधन करें जहां e.Boss == e और kaboom: मार्शलिंग विफल हो जाती है और आपको त्रुटि दिखाई नहीं देगी। ** कभी भी किसी भी त्रुटि को अनदेखा नहीं करें। – Volker

+0

मैं इस पर @ वोल्कर के साथ हूं: इस त्रुटि को अनदेखा करने के बजाय केवल 'दहशत'। यह 'शून्य' धीमी गति के लिए केवल एक ही जांच है, लेकिन आपको मुश्किल से खोजने वाली बग की संभावना के अधीन नहीं होगा। यदि आपको ऐसा लगता है, तो एक सहायक कार्य 'MustMarshal() 'बनाएं। – kostix

+1

हां, मैं आमतौर पर हमेशा त्रुटियों की जांच करता हूं ... लेकिन यह प्रश्न एक अच्छी तरह से परिभाषित प्रकार से होने वाली त्रुटि की संभावना को समझने के बारे में अधिक था। मैं मानता हूं कि जैसे ही कोड बढ़ता है और इस तथ्य पर निर्भर होने पर अधिक जटिल हो जाता है, अगर मैं इसे अभ्यास के रूप में अनदेखा करता हूं तो मुझे काटने के लिए वापस आ सकता है। –

उत्तर

7

Error handling and Go:

उचित त्रुटि हैंडलिंग अच्छा सॉफ्टवेयर का एक अनिवार्य आवश्यकता है उदाहरण के लिए, यदि आप एक प्रवेश प्रणाली की स्थापना की है, तो आप एक छोटे पैकेज है कि तरह लग रहा है का निर्माण हो सकता है।


आम तौर पर अपने कोड असफल नहीं होंगे। लेकिन उपयोगकर्ता अपने प्रकार को यह MarshalJSON विधि reciver जोड़ता है, यह विफल रहता है:

func (t *Employee) MarshalJSON() ([]byte, error) { 
    if t.Id == 2 { 
     return nil, fmt.Errorf("Forbiden Id = %d", t.Id) 
    } 
    data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id)) 
    return data, nil 
} 

इस कोड को संकलित करता है, लेकिन सिर्फ Id == 2 के लिए उद्देश्य पर विफल रहता है (The Go Playground):

package main 

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

type Employee struct { 
    Id int "json:id" 
} 

func main() { 
    b, err := json.Marshal(&Employee{Id: 2}) 
    if err != nil { 
     log.Fatal("Couldn't marshal the Employee", err) 
    } 

    fmt.Println(string(b)) 
} 

func (t *Employee) MarshalJSON() ([]byte, error) { 
    if t.Id == 2 { 
     return nil, fmt.Errorf("Forbiden Id = %d", t.Id) 
    } 
    data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id)) 
    return data, nil 
} 

यह कोड संकलित करता है, लेकिन विफल रहता है (The Go Playground):

package main 

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

type Employee struct { 
    Id int "json:id" 
} 

func main() { 
    b, err := json.Marshal(&Employee{Id: 2}) 
    if err != nil { 
     log.Fatal("Couldn't marshal the Employee") 
    } 

    fmt.Println(string(b)) 
} 

func (t Employee) MarshalJSON() ([]byte, error) { 
    data := []byte(fmt.Sprint(t)) 
    return data, nil 
} 

0

तुम हमेशा व्यवहार कि अन्यथा बॉयलरप्लेट हो सकता है की रचना करने के अपने खुद के "आवरण" संकुल लिख सकते हैं।

package json 
import (
    "encoding/json" 
    "log" 
) 
func TryMarshal(v interface{}) []byte { 
    b, err := json.Marshal(v) 
    if err != nil { 
    log.Println(err) 
    return nil 
    } 
    return b 
} 
संबंधित मुद्दे