JSON को डिकोड करने के लिए प्रकार के साथ स्ट्रिंग से फ्लोट64 में कैसे बदलें


86

मुझे फ्लोट संख्या जैसे JSON स्ट्रिंग को डीकोड करने की आवश्यकता है:

{"name":"Galaxy Nexus", "price":"3460.00"}

मैं नीचे दिए गए गोलांग कोड का उपयोग करता हूं:

package main

import (
    "encoding/json"
    "fmt"
)

type Product struct {
    Name  string
    Price float64
}

func main() {
    s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
    var pro Product
    err := json.Unmarshal([]byte(s), &pro)
    if err == nil {
        fmt.Printf("%+v\n", pro)
    } else {
        fmt.Println(err)
        fmt.Printf("%+v\n", pro)
    }
}

जब मैं इसे चलाता हूं, तो परिणाम प्राप्त करें:

json: cannot unmarshal string into Go value of type float64
{Name:Galaxy Nexus Price:0}

मैं जानना चाहता हूं कि टाइप कन्वर्ट के साथ JSON स्ट्रिंग को कैसे डिकोड किया जाए।

जवाबों:


170

जवाब काफी कम जटिल है। बस यह बताएं कि JSON इंटरपेटर यह एक स्ट्रिंग एन्कोडेड फ्लोट64 है ,string(ध्यान दें कि मैंने केवल Priceपरिभाषा बदल दी है ):

package main

import (
    "encoding/json"
    "fmt"
)

type Product struct {
    Name  string
    Price float64 `json:",string"`
}

func main() {
    s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
    var pro Product
    err := json.Unmarshal([]byte(s), &pro)
    if err == nil {
        fmt.Printf("%+v\n", pro)
    } else {
        fmt.Println(err)
        fmt.Printf("%+v\n", pro)
    }
}

धन्यवाद! मुझे लगता है कि यह मेरी समस्या का सबसे अच्छा समाधान है। क्या आप मुझे बता सकते हैं कि "स्ट्रिंग" के उपयोग के बारे में आधिकारिक दस्तावेज कहां है?
यानून

3
ध्यान दें कि सामने json:",string"स्थित अल्पविराम आवश्यक है - यह इसके बिना काम नहीं करेगा।
डार्र्र्र्र्र्रेंन 25'14

1
@ किसी भी विचार कैसे करने के लिए कि अन्य तरह से चारों ओर? स्ट्रिंग जाने के लिए json नंबर कन्वर्ट करें? उदाहरण के "N": 1234लिए N: "1234"?
कामिल डिजिडिज़िक

यह वास्तव में बहुत बढ़िया है। सिवाय इसके कि यह स्लाइस पर काम नहीं करता है। क्या किसी को एक तरीका पता है कि यह कैसे करना है [] int? बस "जोड़ने, स्ट्रिंग" ध्वज का उत्पादन करता है: "int के जाने मूल्य में स्ट्रिंग को अनमोल नहीं कर सकता" ( play.golang.org/p/aFWSH4lUxv )
Dalibor

@KamilDziedzic क्या आपको अपनी क्वेरी का हल मिला?
मैवरिक

12

बस आपको बताएंगे कि आप ऐसा कर सकते हैं Unmarshalऔर उपयोग नहीं कर सकते json.decode। यहां गो प्लेग्राउंड है

package main

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

type Product struct {
    Name  string `json:"name"`
    Price float64 `json:"price,string"`
}

func main() {
    s := `{"name":"Galaxy Nexus","price":"3460.00"}`
    var pro Product
    err := json.NewDecoder(strings.NewReader(s)).Decode(&pro)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(pro)
}

4

[] बाइट के लिए एक स्ट्रिंग परिवर्तित करने से बचें b := []byte(s):। यह एक नई मेमोरी स्पेस आवंटित करता है और इसमें संपूर्ण सामग्री को कॉपी करता है।

strings.NewReaderइंटरफ़ेस बेहतर है। नीचे गोडॉक का कोड है:

package main

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

func main() {
    const jsonStream = `
    {"Name": "Ed", "Text": "Knock knock."}
    {"Name": "Sam", "Text": "Who's there?"}
    {"Name": "Ed", "Text": "Go fmt."}
    {"Name": "Sam", "Text": "Go fmt who?"}
    {"Name": "Ed", "Text": "Go fmt yourself!"}
`
    type Message struct {
        Name, Text string
    }
    dec := json.NewDecoder(strings.NewReader(jsonStream))
    for {
        var m Message
        if err := dec.Decode(&m); err == io.EOF {
            break
        } else if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s: %s\n", m.Name, m.Text)
    }
}

आपका उत्तर एक बढ़िया बिंदु है जो मैंने उद्धृत किया है। क्या मैंने इसे जोड़ा? देखें stackoverflow.com/a/62740786/12817546
टॉम एल

3

उद्धरण चिह्नों में एक मान पास करने से यह स्ट्रिंग जैसा दिखता है। बदलें "price":"3460.00"करने के लिए "price":3460.00और सब कुछ ठीक काम करता है।

यदि आप उद्धरण चिह्नों को नहीं छोड़ सकते, तो आपको इसका उपयोग करके स्वयं को पार्स करना होगा strconv.ParseFloat:

package main

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

type Product struct {
    Name       string
    Price      string
    PriceFloat float64
}

func main() {
    s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
    var pro Product
    err := json.Unmarshal([]byte(s), &pro)
    if err == nil {
        pro.PriceFloat, err = strconv.ParseFloat(pro.Price, 64)
        if err != nil { fmt.Println(err) }
        fmt.Printf("%+v\n", pro)
    } else {
        fmt.Println(err)
        fmt.Printf("%+v\n", pro)
    }
}

क्या कोई ऐसा तरीका है जो 'उत्पाद' संरचना को नहीं बदल रहा है और स्ट्रिंग को फ्लोट करने के लिए पार्स फ़ंक्शन या इंटरफ़ेस को लागू करना है?
यानून

1
@yanunon हाँ, आप प्रकार के नक्शे का उपयोग कर सकते हैं map[string]interface{}के लिए Unmarshal, और पार्स है कि आपके struct में।
मोस्टफा

@yanunon या यदि आप वास्तविक लचीलापन चाहते हैं , तो आप अपना स्वयं का लिख ​​सकते हैं Unmarshal, जो डिफ़ॉल्ट रूप Unmarshalसे कॉल map[string]interface{}करता है, लेकिन पार्स करने के लिए उपयोग करता है reflectऔर strconvपैकेज करता है ।
मोस्टफा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.