如何从 map[string]interface{} 中提取数据?

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

How to extract data from map[string]interface{}?

问题

我正在将数据发送到API,如下所示:

  1. {"after": {"amount": 811,"id":123,"status":"Hi"}, "key": [70]}

并且在打印时我得到以下结果:

  1. map[after:map[amount:811 id:123 status:Hi ] key:[70]]

有没有办法像这样打印单个字段呢?
amount::800
id:123
status:Hi

代码如下:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "strings"
  10. )
  11. var (
  12. PORT = ":8080"
  13. )
  14. func main() {
  15. fmt.Println("In Main")
  16. http.HandleFunc("/", changedData)
  17. http.ListenAndServe(PORT, nil)
  18. }
  19. type Data struct {
  20. Id int64 `json:"id"`
  21. Amount float64 `json:"amount"`
  22. Status string `json:"status"`
  23. }
  24. type mark map[string]interface{}
  25. func changedData(w http.ResponseWriter, r *http.Request) {
  26. fmt.Println("Coming From API")
  27. reqBody, _ := ioutil.ReadAll(r.Body)
  28. fmt.Println("Data coming from API ", string(reqBody))
  29. digit := json.NewDecoder(strings.NewReader(string(reqBody)))
  30. for digit.More() {
  31. var result mark
  32. err := digit.Decode(&result)
  33. if err != nil {
  34. if err != io.EOF {
  35. log.Fatal(err)
  36. }
  37. break
  38. }
  39. fmt.Println("final_data ", result)
  40. }
  41. }
英文:

I am sending the data to the API like following:

  1. {"after": {"amount": 811,"id":123,"status":"Hi"}, "key": [70]}

and i am getting following while printing :

  1. map[after:map[amount:811 id:123 status:Hi ] key:[70]]

Is there any way to print individual field like this??
amount::800
id:123
status:Hi

The code:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "strings"
  10. )
  11. var (
  12. PORT = ":8080"
  13. )
  14. func main() {
  15. fmt.Println("In Main")
  16. http.HandleFunc("/", changedData)
  17. http.ListenAndServe(PORT, nil)
  18. }
  19. type Data struct {
  20. Id int64 `json:"id"`
  21. Amount float64 `json:"amount"`
  22. Status string `json:"status"`
  23. }
  24. type mark map[string]interface{}
  25. func changedData(w http.ResponseWriter, r *http.Request) {
  26. fmt.Println("Coming From API")
  27. reqBody, _ := ioutil.ReadAll(r.Body)
  28. fmt.Println("Data coming from API ", string(reqBody))
  29. digit := json.NewDecoder(strings.NewReader(string(reqBody)))
  30. for digit.More() {
  31. var result mark
  32. err := digit.Decode(&result)
  33. if err != nil {
  34. if err != io.EOF {
  35. log.Fatal(err)
  36. }
  37. break
  38. }
  39. fmt.Println("final_data ", result)
  40. }
  41. }

答案1

得分: 2

将其解码为与JSON文档结构匹配的Go类型。您为“after”字段声明了一个类型。将该类型与一个结构体包装以匹配文档。

  1. func changedData(w http.ResponseWriter, r *http.Request) {
  2. var v struct{ After Data }
  3. err := json.NewDecoder(r.Body).Decode(&v)
  4. if err != nil {
  5. http.Error(w, "bad request", 400)
  6. return
  7. }
  8. fmt.Printf("final_data: %#v", v.After)
  9. }

Playground示例

英文:

Decode to a Go type that matches the structure of the JSON document. You declared a type for the "after" field. Wrap that type with a struct to match the document.

  1. func changedData(w http.ResponseWriter, r *http.Request) {
  2. var v struct{ After Data }
  3. err := json.NewDecoder(r.Body).Decode(&v)
  4. if err != nil {
  5. http.Error(w, "bad request", 400)
  6. return
  7. }
  8. fmt.Printf("final_data: %#v", v.After)
  9. }

Playground example.

答案2

得分: 1

我认为如果你了解JSON文件的格式,或者JSON格式是预定义的,你可以定义一个struct类型。据我所知,当你不知道JSON格式或者没有预定义的格式时,大多数情况下使用interface{}是一种方法。如果你定义了一个struct类型并在将JSON解组为结构体时使用它,你可以通过像data.Iddata.Status这样的方式访问变量。

这是一个示例代码:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Data struct {
  7. AfterData After `json:"after"`
  8. Key []int `json:"key"`
  9. }
  10. type After struct {
  11. Id int64 `json:"id"`
  12. Amount float64 `json:"amount"`
  13. Status string `json:"status"`
  14. }
  15. func main() {
  16. j := []byte(`{"after": {"amount": 811,"id":123,"status":"Hi"}, "key": [70]}`)
  17. var data *Data
  18. err := json.Unmarshal(j, &data)
  19. if err != nil {
  20. fmt.Println(err.Error())
  21. return
  22. }
  23. fmt.Println(data.AfterData)
  24. fmt.Println(data.AfterData.Id)
  25. fmt.Println(data.AfterData.Amount)
  26. fmt.Println(data.AfterData.Status)
  27. }

输出将会是:

  1. {123 811 Hi}
  2. 123
  3. 811
  4. Hi

Go Playground

英文:

I think you can define a struct type if you know the JSON file format or if the JSON format is predefined. As far as I know that mostly using interface{} is a way when you don't know the JSON format or there is no predefined format of the JSON. If you define a struct type  and use it while unmarshaling the JSON to struct, you can access the variables by typing like data.Id or data.Status.

Here's an example code:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Data struct {
  7. AfterData After `json:"after"`
  8. Key []int `json:"key"`
  9. }
  10. type After struct {
  11. Id int64 `json:"id"`
  12. Amount float64 `json:"amount"`
  13. Status string `json:"status"`
  14. }
  15. func main() {
  16. j := []byte(`{"after": {"amount": 811,"id":123,"status":"Hi"}, "key": [70]}`)
  17. var data *Data
  18. err := json.Unmarshal(j, &data)
  19. if err != nil {
  20. fmt.Println(err.Error())
  21. return
  22. }
  23. fmt.Println(data.AfterData)
  24. fmt.Println(data.AfterData.Id)
  25. fmt.Println(data.AfterData.Amount)
  26. fmt.Println(data.AfterData.Status)
  27. }

Output will be

  1. {123 811 Hi}
  2. 123
  3. 811
  4. Hi

Go Playground

huangapple
  • 本文由 发表于 2021年11月14日 00:40:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/69956272.html
匿名

发表评论

匿名网友

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

确定