无法在 Golang 代码中访问 JSON 元素。

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

Cannot access JSON elements in Golang code

问题

我有以下的Golang代码:

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"strings"
)

func someFunc() {
	output := `
	{
		"predictions": [
		  {
			"displayNames": [
			  "AAA",
			  "BBB",
			  "CCC",
			  "DDD",
			  "EEE",
			  "FFF",
			  "GGG",
			  "HHH"
			],
			"confidences": [
			  0.99998986721038818,
			  5.3742646741739009e-06,
			  1.7922732240549522e-06,
			  1.5455394475338835e-07,
			  3.2323268328582344e-07,
			  6.80681324638499e-08,
			  9.2994454803374538e-08,
			  2.317885900993133e-06
			],
			"ids": [
			  "552624439724867584",
			  "7470153467365949440",
			  "6317231962759102464",
			  "8911305348124508160",
			  "4011388953545408512",
			  "2858467448938561536",
			  "5164310458152255488",
			  "1705545944331714560"
			]
		  }
		],
		"deployedModelId": "ABC123",
		"model": "myOwnModel",
		"modelDisplayName": "myDisplayName",
		"modelVersionId": "1"
	}`
	var outputJson map[string]interface{}
	json.Unmarshal([]byte(output), &outputJson)

	// names := outputJson["predictions"].(data)[0].(data)["displayNames"].(data)
	// ids := outputJson["predictions"].(data)[0].(data)["ids"].(data)
	// confidences := outputJson["predictions"].(data)[0].(data)["confidences"].(data)
	// fmt.Printf(fmt.Sprintf("Names:\n%s\n", names))
	// fmt.Printf(fmt.Sprintf("IDs:\n%s\n", ids))
	// fmt.Printf(fmt.Sprintf("Confidences:\n%s\n", confidences))

	fmt.Println("something")
}

func main() {
	someFunc()
}

我想从outputJson中访问displayNamesidsconfidences元素。我使用VS Code来检查它们的位置,并将它们添加到监视列表中。

无法在 Golang 代码中访问 JSON 元素。

然后,我将位置字符串复制到我的代码中。然而,代码中显示的情况并不像图片中那样工作。报错显示data未定义。为什么会发生这种情况,我该如何访问这些元素?为什么在监视窗口中data可以工作,但在代码中却不行?

英文:

I have the following Golang code:

package main

import (
	"bytes"
	"encoding/json"
	"fmt"	
	"strings"
)

func someFunc() {
	output := `
	{
		"predictions": [
		  {
			"displayNames": [
			  "AAA",
			  "BBB",
			  "CCC",
			  "DDD",
			  "EEE",
			  "FFF",
			  "GGG",
			  "HHH"
			],
			"confidences": [
			  0.99998986721038818,
			  5.3742646741739009e-06,
			  1.7922732240549522e-06,
			  1.5455394475338835e-07,
			  3.2323268328582344e-07,
			  6.80681324638499e-08,
			  9.2994454803374538e-08,
			  2.317885900993133e-06
			],
			"ids": [
			  "552624439724867584",
			  "7470153467365949440",
			  "6317231962759102464",
			  "8911305348124508160",
			  "4011388953545408512",
			  "2858467448938561536",
			  "5164310458152255488",
			  "1705545944331714560"
			]
		  }
		],
		"deployedModelId": "ABC123",
		"model": "myOwnModel",
		"modelDisplayName": "myDisplayName",
		"modelVersionId": "1"
	}`
	var outputJson map[string]interface{}
	json.Unmarshal([]byte(output), &outputJson)

	// names := outputJson["predictions"].(data)[0].(data)["displayNames"].(data)
	// ids := outputJson["predictions"].(data)[0].(data)["ids"].(data)
	// confidences := outputJson["predictions"].(data)[0].(data)["confidences"].(data)
	// fmt.Printf(fmt.Sprintf("Names:\n%s\n", names))
	// fmt.Printf(fmt.Sprintf("IDs:\n%s\n", ids))
	// fmt.Printf(fmt.Sprintf("Confidences:\n%s\n", confidences))

	fmt.Println("something")
}

func main() {
	someFunc()
}

I want to access the displayNames, ids, and confidences elements from outputJson. I use VS Code to check their locations, and add them to the watch list.

无法在 Golang 代码中访问 JSON 元素。

I then copy the location strings into my code. However, it doesn't work as shown in the picture. The complain is that data is undefined. Why is this happening, and what can I do to access these elements? Why does this data works in the watch window, but not in the code?

答案1

得分: 1

你需要通过类型断言来处理outputJson

p := outputJson["predictions"]
if x, ok := p.([]interface{}); ok {
	if y, ok := x[0].(map[string]interface{}); ok {
		fmt.Println(y["displayNames"])
	}
}

但是,更好的方法是,既然你不需要解码任意的 JSON,就定义一个 Golang 类型树,然后将其解组为该类型:

type Output struct {
	Predictions []Prediction `json:"predictions"`
}
type Prediction struct {
	DisplayNames []string `json:"displayNames"`
    // Confidences ...
}

func main() {

    ...
    foo := &Output{}
	if err := json.Unmarshal([]byte(output), foo); err == nil {
		fmt.Println(foo.Predictions[0].DisplayNames)
	}
}
英文:

You need to type assert your way through the outputJson:

p := outputJson["predictions"]
if x, ok := p.([]interface{}); ok {
	if y, ok := x[0].(map[string]interface{}); ok {
		fmt.Println(y["displayNames"])
	}
}

But, a better approach, given that you don't need to decode arbitrary JSON, is to define a tree of Golang types and then unmarshal into it:

type Output struct {
	Predictions []Prediction `json:"predictions"`
}
type Prediction struct {
	DisplayNames []string `json:"displayNames"`
    // Confidences ...
}

func main() {

    ...
    foo := &Output{}
	if err := json.Unmarshal([]byte(output), foo); err == nil {
		fmt.Println(foo.Predictions[0].DisplayNames)
	}
}

huangapple
  • 本文由 发表于 2023年4月4日 11:48:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925369.html
匿名

发表评论

匿名网友

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

确定