2012-02-26 5 views
54

muszę rozszyfrować ciąg JSON z numerem pływaka jak:Jak rozszyfrować JSON z typem konwersji z ciągu na float64 w Golang?

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

użyć 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) 
    } 
} 

Podczas uruchamiania go uzyskać wynik:

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

Chcę wiedzieć, jak rozszyfrować ciąg JSON z konwersją typu.

Odpowiedz

112

Odpowiedź jest znacznie mniej skomplikowana. Wystarczy dodać powiedzieć JSON interpeter to ciąg zakodowany float64 z ,string (zauważ, że ja tylko zmieniła definicję 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) 
    } 
} 
+0

Dziękujemy! Myślę, że to najlepsze rozwiązanie mojego problemu. Czy możesz mi powiedzieć, gdzie jest oficjalny dokument na temat używania "string"? – yanunon

+5

Znalazłem go na [link] (http://weekly.golang.org/pkg/encoding/json/). – yanunon

+0

+1 To jest niesamowite. Nie wiedziałem o tym. – Mostafa

5

Podanie wartości w cudzysłowach powoduje, że wygląda ona jak ciąg. Zmień "price":"3460.00" na "price":3460.00 i wszystko działa poprawnie.

Jeśli nie może spaść notowań wyznacza trzeba analizować je przez siebie, 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) 
    } 
} 
+0

Czy istnieje sposób, że nie zmienia struct „produkt” i zaimplementować funkcję dekodowania lub interfejs do analizowania ciąg do pływaka? – yanunon

+1

@yanunon Tak, możesz użyć mapy typu 'map [string] interface {}' dla 'Unmarshal' i przeanalizuj to w swojej strukturze. – Mostafa

+0

@yanunon Lub jeśli chcesz ** prawdziwej ** elastyczności, możesz napisać własny 'Unmarshal', który wywołuje domyślny' Unmarshal' z 'map [string] interface {}', ale używa 'reflect' i' strconv' pakiety do wykonania parsowania. – Mostafa

4

tylko z powiadomieniem, że można to zrobić bez Unmarshal i używać json.decode. Oto Go Playground

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) 
} 
Powiązane problemy