2012-02-26 29 views
54

tôi cần phải giải mã một chuỗi JSON với số thập phân như:Làm thế nào để giải mã JSON với kiểu chuyển đổi từ chuỗi thành float64 trong Golang?

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

tôi sử dụng mã Golang dưới đây:

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) 
    } 
} 

Khi tôi chạy nó, có được kết quả:

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

Tôi muốn biết cách giải mã chuỗi JSON bằng chuyển đổi kiểu.

Trả lời

112

Câu trả lời là đáng kể ít phức tạp hơn. Chỉ cần thêm kể JSON interpeter đó là một chuỗi mã hóa float64 với ,string (lưu ý rằng tôi chỉ thay đổi định nghĩa 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

Cảm ơn bạn! Tôi nghĩ đây là giải pháp tốt nhất cho vấn đề của tôi. Bạn có thể cho tôi biết tài liệu chính thức về việc sử dụng ", chuỗi" ở đâu không? – yanunon

+5

Tôi tìm thấy nó trên [link] (http://weekly.golang.org/pkg/encoding/json/). – yanunon

+0

+1 Thật tuyệt vời. Tôi không biết về nó. – Mostafa

5

Truyền giá trị trong dấu ngoặc kép làm cho chuỗi đó trông giống như chuỗi. Thay đổi "price":"3460.00" thành "price":3460.00 và mọi thứ hoạt động tốt.

Nếu bạn không thể thả những trích dẫn đánh dấu bạn phải phân tích nó một mình, sử dụng 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

Có cách nào không thay đổi 'Sản phẩm' cấu trúc và triển khai chức năng giải mã hoặc giao diện để phân tích chuỗi nổi không? – yanunon

+1

@yanunon Có, bạn có thể sử dụng một bản đồ kiểu 'map [string] interface {}' cho 'Unmarshal', và phân tích cú pháp đó thành cấu trúc của bạn. – Mostafa

+0

@yanunon Hoặc nếu bạn muốn ** thực ** linh hoạt, bạn có thể viết 'Unmarshal' của riêng bạn, gọi mặc định là 'Unmarshal' với một giao diện' map [string] {} ', nhưng sử dụng' reflect' và 'strconv' các gói để thực hiện phân tích cú pháp. – Mostafa

4

chỉ cho bạn biết rằng bạn có thể làm điều này mà không Unmarshal và sử dụng json.decode. Đây là 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) 
} 
Các vấn đề liên quan