क्योंकि मैं अक्सर http.Response.Body को अनमर्शल करता हूं, मैंने सोचा कि मैं एक ऐसा फंक्शन लिख सकता हूं जो विभिन्न विभिन्न स्ट्रक्चर्स में पढ़ने, बंद करने और अनमर्शलिंग के सभी झंझटों को संभालता है। इसलिए मैंने एक फ़ंक्शन func unmarhalInterface(closer *io.ReadCloser, v *interface{}) error पेश किया और फिर t:=i.(T) के साथ वापसी मान पर जोर दे सकता है।

this answer के अनुसार मैंने इसे पहले ही *interface{} प्रकार के मान में लपेट लिया है, लेकिन क्योंकि अतिव्यापी प्रकार है interface{}और myStruct नहीं, json पैकेज कार्यान्वयन map[string]interface{} को चुनता है। उसके बाद एक प्रकार का दावा विफल रहता है (बेशक)। क्या मुझे कुछ याद आ रहा है या इस कार्यान्वयन की आवश्यकता है "हाथ से" एक प्रकार का दावा, इसका मतलब है कि मानचित्र में सभी फ़ील्ड देखें और उन्हें असाइन करें जिन्हें मैं अपनी संरचना में चाहता हूं।

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

package main

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

type myStruct struct {
    A string `json:"a"`
    B string `json:"b"`
}

func main() {
    jsonBlob := []byte(`{"a":"test","b":"test2"}`)

    var foo = interface{}(myStruct{})
    closer := ioutil.NopCloser(bytes.NewReader(jsonBlob))

    err := unmarshalCloser(&closer, &foo)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(fmt.Sprintf("%v", foo))

    // That´s what i want:
    foo2 := foo.(myStruct)
    fmt.Println(foo2.A)
}

func unmarshalCloser(closer *io.ReadCloser, v *interface{}) error {
    defer func() { _ = (*closer).Close() }()

    data, err := ioutil.ReadAll(*closer)
    if err != nil {
        return err
    }

    err = json.Unmarshal(data, v)
    if err != nil {
        return err
    }
    return nil
}

गोलांग खेल का मैदान

-2
sHartmann 19 जून 2019, 20:37

1 उत्तर

सबसे बढ़िया उत्तर

एक खाली इंटरफ़ेस वास्तविक प्रकार नहीं है, यह मूल रूप से ऐसा कुछ है जो किसी भी चीज़ से मेल खाता है। जैसा कि टिप्पणियों में कहा गया है, एक खाली इंटरफ़ेस के लिए एक सूचक वास्तव में समझ में नहीं आता है क्योंकि एक सूचक पहले से ही एक खाली इंटरफ़ेस से मेल खाता है क्योंकि सब कुछ एक खाली इंटरफ़ेस से मेल खाता है। अपना कोड काम करने के लिए, आपको अपनी संरचना के चारों ओर इंटरफ़ेस रैपर को हटा देना चाहिए, क्योंकि यह सिर्फ जेसन प्रकार की जांच को गड़बड़ कर रहा है, और एक खाली इंटरफ़ेस का पूरा बिंदु यह है कि आप इसे कुछ भी पास कर सकते हैं।

package main

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

type myStruct struct {
    A string `json:"a"`
    B string `json:"b"`
}

func main() {
    jsonBlob := []byte(`{"a":"test","b":"test2"}`)

    var foo = &myStruct{} // This need to be a pointer so its attributes can be assigned
    closer := ioutil.NopCloser(bytes.NewReader(jsonBlob))

    err := unmarshalCloser(closer, foo)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(fmt.Sprintf("%v", foo))

    // That´s what i want:
    fmt.Println(foo.A)
}

// You don't need to declare either of these arguments as pointers since they're both interfaces
func unmarshalCloser(closer io.ReadCloser, v interface{}) error {
    defer closer.Close()
    // v NEEDS to be a pointer or the json stuff will barf

    // Simplified with the decoder
    return json.NewDecoder(closer).Decode(v)
}
1
Tim Brown 20 जून 2019, 01:44