英文:
Custom unmarshalling from flat json to nested struct
问题
假设我有两个相关的结构体,如下所示:
type SecretUser struct {
UserInfo `json:"userInfo"`
Password string `json:"password"`
}
type UserInfo struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Email string `json:"email"`
}
我收到的JSON数据如下所示:
{
"firstName": "nice",
"lastName": "guy",
"email": "nice@guy.co.uk",
"password": "abc123"
}
我想将这个JSON数据解组成一个SecretUser结构体。有没有比下面这种方法更好的方式?
func (u *User) UnmarshalJSON(data []byte) error {
var objmap map[string]*json.RawMessage
var password string
var err error
err = json.Unmarshal(data, &objmap)
if err != nil {
return err
}
if err := json.Unmarshal(data, &u.UserInfo); err != nil {
return err
}
err = json.Unmarshal(*objmap["password"], &password)
if err != nil {
return err
}
u.Password = password
return nil
}
基本上,我将JSON数据部分解组成一个UserInfo结构体,然后再次读取它以提取密码。我不想为了清晰地解组这个JSON数据而创建另一个结构体,也不想使用外部库(除非它是标准库的一部分)。有没有更清晰/高效的方法来做到这一点,而不需要两次读取JSON数据或手动从映射中设置每个字段?
英文:
Lets say I have two struct that are related like this:
type SecretUser struct {
UserInfo `json:"userInfo"`
Password string `json:"password"`
}
type UserInfo struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Email string `json:"email"`
}
And I receive a JSON in this form:
{
"firstName": "nice",
"lastName":"guy",
"email":"nice@guy.co.uk",
"password":"abc123"
}
I want to unmarshall this JSON into a SecretUser. Is there a better way than doing it like this?
func (u *User) UnmarshalJSON(data []byte) error {
var objmap map[string]*json.RawMessage
var password string
var err error
err = json.Unmarshal(data, &objmap)
if err != nil {
return err
}
if err := json.Unmarshal(data, &u.UserInfo); err != nil {
return err
}
err = json.Unmarshal(*objmap["password"], &password)
if err != nil {
return err
}
u.Password = password
return nil
}
Basically, I partially unmarshall the JSON into a UserInfo struct and then read it again to extract the password. I don't want to create another struct for just unmarshalling this JSON cleanly or use an external library (unless it's part of the standard). Is there a more clean/efficient way of doing this, without reading the JSON twice or setting every field manually from a map?
答案1
得分: 1
只需将UserData包含在SecretUser结构体中,并且不为其指定json标签。
type UserInfo struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Email string `json:"email"`
}
type SecretUser struct {
UserInfo
Password string `json:"password"`
}
func main() {
data := []byte(`{"firstName": "nice","lastName":"guy","email":"nice@guy.co.uk","password":"abc123"}`)
var u SecretUser
json.Unmarshal(data, &u)
fmt.Println(u)
}
英文:
Simply include the UserData into the SecretUser struct and do not specify a json tag for it.
type UserInfo struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Email string `json:"email"`
}
type SecretUser struct {
UserInfo
Password string `json:"password"`
}
func main() {
data := []byte(`{"firstName": "nice","lastName":"guy","email":"nice@guy.co.uk","password":"abc123"}`)
var u SecretUser
json.Unmarshal(data, &u)
fmt.Println(u)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论