如何将字符串转换为float64类型并解码JSON

huangapple go评论116阅读模式
英文:

How to decode JSON with type convert from string to float64

问题

我需要解码一个包含浮点数的JSON字符串,例如:

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

我使用以下的Golang代码:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Product struct {
  7. Name string
  8. Price float64
  9. }
  10. func main() {
  11. s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
  12. var pro Product
  13. err := json.Unmarshal([]byte(s), &pro)
  14. if err == nil {
  15. fmt.Printf("%+v\n", pro)
  16. } else {
  17. fmt.Println(err)
  18. fmt.Printf("%+v\n", pro)
  19. }
  20. }

当我运行它时,得到的结果是:

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

我想知道如何进行类型转换来解码JSON字符串。

英文:

I need to decode a JSON string with the float number like:

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

I use the Golang code below:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Product struct {
  7. Name string
  8. Price float64
  9. }
  10. func main() {
  11. s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
  12. var pro Product
  13. err := json.Unmarshal([]byte(s), &pro)
  14. if err == nil {
  15. fmt.Printf("%+v\n", pro)
  16. } else {
  17. fmt.Println(err)
  18. fmt.Printf("%+v\n", pro)
  19. }
  20. }

When I run it, get the result:

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

I want to know how to decode the JSON string with type convert.

答案1

得分: 221

答案相对简单。只需告诉JSON解释器它是一个编码为float64的字符串,使用,string(请注意,我只改变了Price的定义):

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Product struct {
  7. Name string
  8. Price float64 `json:",string"`
  9. }
  10. func main() {
  11. s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
  12. var pro Product
  13. err := json.Unmarshal([]byte(s), &pro)
  14. if err == nil {
  15. fmt.Printf("%+v\n", pro)
  16. } else {
  17. fmt.Println(err)
  18. fmt.Printf("%+v\n", pro)
  19. }
  20. }
英文:

The answer is considerably less complicated. Just add tell the JSON interpeter it's a string encoded float64 with ,string (note that I only changed the Price definition):

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Product struct {
  7. Name string
  8. Price float64 `json:",string"`
  9. }
  10. func main() {
  11. s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
  12. var pro Product
  13. err := json.Unmarshal([]byte(s), &pro)
  14. if err == nil {
  15. fmt.Printf("%+v\n", pro)
  16. } else {
  17. fmt.Println(err)
  18. fmt.Printf("%+v\n", pro)
  19. }
  20. }

答案2

得分: 21

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

英文:

Just letting you know that you can do this without Unmarshal and use json.decode. Here is Go Playground

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. )
  7. type Product struct {
  8. Name string `json:"name"`
  9. Price float64 `json:"price,string"`
  10. }
  11. func main() {
  12. s := `{"name":"Galaxy Nexus","price":"3460.00"}`
  13. var pro Product
  14. err := json.NewDecoder(strings.NewReader(s)).Decode(&pro)
  15. if err != nil {
  16. fmt.Println(err)
  17. return
  18. }
  19. fmt.Println(pro)
  20. }

答案3

得分: 6

避免将字符串转换为[]byte:b := []byte(s)。它会分配一个新的内存空间,并将整个内容复制到其中。

strings.NewReader 接口更好。下面是来自 godoc 的代码示例:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "log"
  7. "strings"
  8. )
  9. func main() {
  10. const jsonStream = `
  11. {"Name": "Ed", "Text": "Knock knock."}
  12. {"Name": "Sam", "Text": "Who's there?"}
  13. {"Name": "Ed", "Text": "Go fmt."}
  14. {"Name": "Sam", "Text": "Go fmt who?"}
  15. {"Name": "Ed", "Text": "Go fmt yourself!"}
  16. `
  17. type Message struct {
  18. Name, Text string
  19. }
  20. dec := json.NewDecoder(strings.NewReader(jsonStream))
  21. for {
  22. var m Message
  23. if err := dec.Decode(&m); err == io.EOF {
  24. break
  25. } else if err != nil {
  26. log.Fatal(err)
  27. }
  28. fmt.Printf("%s: %s\n", m.Name, m.Text)
  29. }
  30. }
英文:

Avoid converting a string to []byte: b := []byte(s). It allocates a new memory space and copy the whole the content into it.

strings.NewReader interface is better. Below is the code from godoc:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "log"
  7. "strings"
  8. )
  9. func main() {
  10. const jsonStream = `
  11. {"Name": "Ed", "Text": "Knock knock."}
  12. {"Name": "Sam", "Text": "Who's there?"}
  13. {"Name": "Ed", "Text": "Go fmt."}
  14. {"Name": "Sam", "Text": "Go fmt who?"}
  15. {"Name": "Ed", "Text": "Go fmt yourself!"}
  16. `
  17. type Message struct {
  18. Name, Text string
  19. }
  20. dec := json.NewDecoder(strings.NewReader(jsonStream))
  21. for {
  22. var m Message
  23. if err := dec.Decode(&m); err == io.EOF {
  24. break
  25. } else if err != nil {
  26. log.Fatal(err)
  27. }
  28. fmt.Printf("%s: %s\n", m.Name, m.Text)
  29. }
  30. }

答案4

得分: 4

Passing a value in quotation marks make that look like string. Change "price":"3460.00" to "price":3460.00 and everything works fine.

If you can't drop the quotations marks you have to parse it by yourself, using strconv.ParseFloat:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. )
  7. type Product struct {
  8. Name string
  9. Price string
  10. PriceFloat float64
  11. }
  12. func main() {
  13. s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
  14. var pro Product
  15. err := json.Unmarshal([]byte(s), &pro)
  16. if err == nil {
  17. pro.PriceFloat, err = strconv.ParseFloat(pro.Price, 64)
  18. if err != nil { fmt.Println(err) }
  19. fmt.Printf("%+v\n", pro)
  20. } else {
  21. fmt.Println(err)
  22. fmt.Printf("%+v\n", pro)
  23. }
  24. }
英文:

Passing a value in quotation marks make that look like string. Change "price":"3460.00" to "price":3460.00 and everything works fine.

If you can't drop the quotations marks you have to parse it by yourself, using strconv.ParseFloat:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. )
  7. type Product struct {
  8. Name string
  9. Price string
  10. PriceFloat float64
  11. }
  12. func main() {
  13. s := `{"name":"Galaxy Nexus", "price":"3460.00"}`
  14. var pro Product
  15. err := json.Unmarshal([]byte(s), &pro)
  16. if err == nil {
  17. pro.PriceFloat, err = strconv.ParseFloat(pro.Price, 64)
  18. if err != nil { fmt.Println(err) }
  19. fmt.Printf("%+v\n", pro)
  20. } else {
  21. fmt.Println(err)
  22. fmt.Printf("%+v\n", pro)
  23. }
  24. }

huangapple
  • 本文由 发表于 2012年2月26日 20:05:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/9452897.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定