Muszę zdekodować ciąg JSON z liczbą zmiennoprzecinkową, taką jak:
{"name":"Galaxy Nexus", "price":"3460.00"}
Używam kodu Golang poniżej:
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)
}
}
Kiedy go uruchomię, uzyskaj wynik:
json: cannot unmarshal string into Go value of type float64
{Name:Galaxy Nexus Price:0}
Chcę wiedzieć, jak zdekodować ciąg JSON za pomocą konwersji typu.
json:",string"
jest konieczny - bez niego nie zadziała."N": 1234
doN: "1234"
?Po prostu informuję, że możesz to zrobić bez
Unmarshal
i używaćjson.decode
. Oto Go Playgroundpackage 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) }
źródło
Unikać konwertowania ciąg [] bajt:
b := []byte(s)
. Alokuje nową przestrzeń pamięci i kopiuje do niej całą zawartość.strings.NewReader
interfejs jest lepszy. Poniżej znajduje się kod z Godoc: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) } }
źródło
Przekazanie wartości w cudzysłowie sprawia, że wygląda ona jak ciąg. Zmień
"price":"3460.00"
na"price":3460.00
i wszystko działa dobrze.Jeśli nie możesz upuścić cudzysłowów, musisz przeanalizować go samodzielnie, używając
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) } }
źródło
map[string]interface{}
dlaUnmarshal
i przeanalizować ją w swojej strukturze.Unmarshal
, który wywołuje defaultUnmarshal
z amap[string]interface{}
, ale używa pakietówreflect
istrconv
do wykonywania analizy.