2013-01-06 22 views
7

मुझे []uint8 सदस्य के साथ एक संरचना मिली है और मैं इसे json.Marshal के साथ लिख रहा हूं। समस्या यह है कि यह uint8 को char एस के रूप में व्याख्या कर रहा है और यह संख्याओं की सरणी के बजाय स्ट्रिंग आउटपुट करता है।गो में जेसन सरणी के रूप में एक बाइट/uint8 सरणी कैसे मार्शल करें?

यदि यह []int है, तो मैं इसे काम पर ला सकता हूं, लेकिन अगर मैं इससे बच सकता हूं तो मैं वस्तुओं को आवंटित और कॉपी नहीं करना चाहता हूं। क्या मैं?

+0

जैसा कि मैंने सवाल में कहा, मैं उपयोग कर रहा हूँ 'json.Marshal'। मेरा सवाल 'एफएमटी' के बारे में नहीं है, यह' जेसन 'लाइब्रेरी के बारे में है। – Joe

+0

(मेरे पास एक टिप्पणी थी कि मैं इसे कैसे आउटपुट कर रहा था, लेखक ने उत्तर देने के बाद इसे हटा दिया। मेरी प्रतिक्रिया भी रख सकती है।) – Joe

उत्तर

13

docs के अनुसार, []byte को बेस 64 स्ट्रिंग के रूप में एन्कोड किया जाएगा।

"सरणी और टुकड़ा मूल्यों सांकेतिक शब्दों में बदलना JSON सरणियों, को छोड़कर के रूप में है कि [] बाइट एक बेस 64 एन्कोडेड स्ट्रिंग के रूप में encodes, और एक नहीं के बराबर टुकड़ा अशक्त JSON ऑब्जेक्ट के रूप एन्कोड करता है।"

तो मुझे लगता है कि आप अपने खुद के MarshalJSON विधि है कि आपके []uint8 के बाहर एक और अधिक वांछनीय JSON सारणी एन्कोडिंग बनाता है को लागू करने से अपने struct Marshaler इंटरफ़ेस को लागू करने के लिए आवश्यकता हो सकती है।

इस उदाहरण लें:

import "fmt" 
import "encoding/json" 
import "strings" 

type Test struct { 
    Name string 
    Array []uint8 
} 

func (t *Test) MarshalJSON() ([]byte, error) { 
    var array string 
    if t.Array == nil { 
     array = "null" 
    } else { 
     array = strings.Join(strings.Fields(fmt.Sprintf("%d", t.Array)), ",") 
    } 
    jsonResult := fmt.Sprintf(`{"Name":%q,"Array":%s}`, t.Name, array) 
    return []byte(jsonResult), nil 
} 

func main() { 
    t := &Test{"Go", []uint8{'h', 'e', 'l', 'l', 'o'}} 

    m, err := json.Marshal(t) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Printf("%s", m) // {"Name":"Go","Array":[104,101,108,108,111]} 
} 

http://play.golang.org/p/Tip59Z9gqs


या हो सकता है एक बेहतर विचार []uint8 उसके अंतर्निहित प्रकार के रूप में है कि एक नए प्रकार बनाने के लिए हो सकता है, उस प्रकार एक Marshaler बनाने के लिए, और अपनी संरचना में उस प्रकार का प्रयोग करें।

import "fmt" 
import "encoding/json" 
import "strings" 

type JSONableSlice []uint8 

func (u JSONableSlice) MarshalJSON() ([]byte, error) { 
    var result string 
    if u == nil { 
     result = "null" 
    } else { 
     result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",") 
    } 
    return []byte(result), nil 
} 

type Test struct { 
    Name string 
    Array JSONableSlice 
} 

func main() { 
    t := &Test{"Go", []uint8{'h', 'e', 'l', 'l', 'o'}} 

    m, err := json.Marshal(t) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Printf("%s", m) // {"Name":"Go","Array":[104,101,108,108,111]} 
} 

http://play.golang.org/p/6aURXw8P5d

+0

शानदार। मुझे लगता है कि दूसरा विकल्प भविष्य में सबूत है। बहुत बहुत धन्यवाद। – Joe

+0

@ जो: आपका स्वागत है। और मैंने 'शून्य' टुकड़ा को 'शून्य' के रूप में संभालने के द्वारा इसे थोड़ा और पूरा करने के लिए अद्यतन किया। –

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