英文:
How to decode JSON object based on key prefix
问题
我在想是否可以根据前缀将JSON对象解码为结构体。
例如,我可能有两个如下的JSON对象:
{
"id teacher": "10"
}
和
{
"id student": "20"
}
目前我有两个结构体:
type Teacher struct {
Id string `json:"id teacher"`
}
type Student struct {
Id string `json:"id student"`
}
我想知道是否可以只使用一个结构体,并根据字符串的前缀(例如,使用正则表达式id.*
)进行解码,假设只会有一个匹配的字段。
英文:
I'm wondering if it is possible to decode a JSON object into struct based on prefix.
For example, I may have two JSON objects like following:
{
"id teacher": "10"
}
and
{
"id student": "20"
}
Currently I have two structs:
type Teacher struct {
Id string `json:"id teacher"`
}
type Student struct {
Id string `json:"id student"`
}
I'm wondering if it is possible to have one struct and decode based on the prefix of the string (for example, by regex id.*
) assuming that there will be only one matching field.
答案1
得分: 2
如果我理解你的意图正确的话,你想创建一个名为Person
的结构体,并且有一个名为Person.Id
的属性,可以由id teacher
或id student
填充。
在原生的encoding/json
语法中,你可能期望看到类似下面的代码,但是Go语言不是这样工作的。
type Person struct {
Id string `json:"id student|id teacher"`
}
一种方法是实现一个自定义的UnmarshalJSON
函数,如下所示。这个例子使用了strings.Index
,但是使用正则表达式也同样简单。
type Person struct {
Id string
Role string
}
func (p *Person) UnmarshalJSON(data []byte) error {
var v map[string]interface{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
for key, val := range v {
if strings.Index(key, "id ") == 0 {
p.Id = val.(string)
p.Role = key[3:]
}
}
return nil
}
这里有一个完整可运行的例子:
https://play.golang.org/p/1-tzUYcd5rJ
英文:
If I understand what you're trying to do, you want to create a single struct for say Person
and have a single property Person.Id
which can be populated by either id teacher
or id student
.
In native encoding/json
syntax, you might expect to see something like the following, but Go doesn't work this way.
type Person struct {
Id string `json:"id student|id teacher"`
}
One approach is to implement a custom UnmarshalJSON
function like follows. This example uses strings.Index
but it's just as easy to use a regular expression.
type Person struct {
Id string
Role string
}
func (p *Person) UnmarshalJSON(data []byte) error {
var v map[string]interface{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
for key, val := range v {
if strings.Index(key, "id ") == 0 {
p.Id = val.(string)
p.Role = key[3:]
}
}
return nil
}
Here's a fully operational example:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论