这个简洁的JSON文档对应的Go结构体是什么?

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

What would be the Go structs for this terse JSON document?

问题

该文档有意地只包含最少的键值对元数据。在人员列表中,我们可以使用"name":"joe"这样的形式,或者使用joe作为键。它倾向于使用更少的键。

也许这个文档对于Go结构体来说太过动态了?我已经尝试了YAML,问题出在结构体上。结构体保持为空,因为映射不正确。

Playground链接:https://play.golang.org/p/PGSjoKvNja

或者我需要自己编写UnmarshalJSON并使用条件语句(或switch)来处理"actions"吗?如果是这样的话也没关系。我可以在那里进行强制转换和验证,遍历文档并检测出问题的通用操作部分,然后创建正确类型的结构体。

英文:

The document has minimal key/value pair metadata on purpose. In a list of people, we could have something like "name":"joe" or we could have a key of joe. It errs on having fewer keys.

Perhaps this document is just too dynamic for Go structs? I've tried YAML as well, it's the structs that's the problem. The structs remain empty because it's not mapping correctly.

Playground link: https://play.golang.org/p/PGSjoKvNja

Or do I need to roll my own UnmarshalJSON and have conditionals (or switch) for "actions"? That's fine if so. I could do coercion and validation in there, loop through the doc and detect what the problematic generic action bit is and then create a struct of the right type.

答案1

得分: 1

如果数据不一致,正如@Adrian所说,你不应该按照我展示的方式进行操作。

否则,你可以使用以下由json-to-go生成的结构体来解析你的字符串,这是一个非常有用的工具,可以将json转换为结构体:

type Custom struct {
    Ball []struct {
        Throw struct {
            Strength string `json:"strength"`
        } `json:"throw"`
    } `json:"ball"`
    Frisbee []struct {
        Fling struct {
            Curve string `json:"curve"`
        } `json:"fling"`
        Catch struct {
            Trick string `json:"trick"`
            Jump  string `json:"jump"`
        } `json:"catch"`
    } `json:"frisbee"`
}

然后,在main函数中:

func main() {
    var c Custom
    err := json.Unmarshal([]byte(input), &c)
    if err != nil {
        panic(err)
    }
    fmt.Println(input)
}

这将输出:

{
    "ball": [
        {
            "throw": {
                "strength": "60%"
            }
        },
        {
            "throw": {
                "strength": "20%"
            }
        }
    ],
    "frisbee": [
        {
            "fling": {
                "curve": "left"
            }
        },
        {
            "catch": {
                "trick": "behind back",
                "jump": "sure"
            }
        }
    ]
}

你可以查看我设置的这个Playground

英文:

If the data is NOT consistent, as @Adrian stated, you should not go for what I'm showing.

Otherwise, you should be able to unmarshal your string with the following struct generated with json-to-go, a very useful tool to get a struct out of a json

type Custom struct {
	Ball []struct {
		Throw struct {
			Strength string `json:"strength"`
		} `json:"throw"`
	} `json:"ball"`
	Frisbee []struct {
		Fling struct {
			Curve string `json:"curve"`
		} `json:"fling"`
		Catch struct {
			Trick string `json:"trick"`
			Jump string `json:"jump"`
		} `json:"catch"`
	} `json:"frisbee"`
}

And then

func main() {

    var c Custom
    err := json.Unmarshal([]byte(input), &c )
    if err != nil {
        panic(err)
    }

     fmt.Println(input)

}

Which prints out

{
	"ball": [{
		"throw": {
			"strength": "60%"
		}
	}, {
		"throw": {
			"strength": "20%"
		}
	}],
	"frisbee": [{
		"fling": {
			"curve": "left"
		}
	}, {
		"catch": {
			"trick": "behind back",
			"jump": "sure"
		}
	}]
}

Have a look at this Playground I set up.

答案2

得分: 1

这是翻译好的内容:

type AutoGenerated struct {
    Ball []struct {
        Throw struct {
            Strength string `json:"strength"`
        } `json:"throw"`
    } `json:"ball"`
    Frisbee []struct {
        Fling struct {
            Curve string `json:"curve"`
        } `json:"fling,omitempty"`
        Catch struct {
            Trick string `json:"trick"`
            Jump  string `json:"jump"`
        } `json:"catch,omitempty"`
    } `json:"frisbee"`
}

当然,你可以为每个内联结构定义一个单独的类型。你可以使用这个在线工具(用于生成上述数据结构)。

英文:

It would be:

type AutoGenerated struct {
	Ball []struct {
		Throw struct {
			Strength string `json:"strength"`
		} `json:"throw"`
	} `json:"ball"`
	Frisbee []struct {
		Fling struct {
			Curve string `json:"curve"`
		} `json:"fling,omitempty"`
		Catch struct {
			Trick string `json:"trick"`
			Jump string `json:"jump"`
		} `json:"catch,omitempty"`
	} `json:"frisbee"`
}

Ofcourse you can define a separate type for each inline struct definition. You can use this online tool (which is used for generating the above data structure).

huangapple
  • 本文由 发表于 2017年6月9日 05:28:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/44445841.html
匿名

发表评论

匿名网友

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

确定