type TemplateCategory struct {
ID int `json:"id"`
Name string `json:"name"`
}
type Template struct {
Name string `json:"name"`
CategoryInfo *TemplateCategoryType `json:"category_info"`
}
type TemplateCategoryType struct {
*TemplateCategory
}
func (t *TemplateCategoryType) UnmarshalJSON(b []byte) error {
s := strings.Trim(string(b), "\"")
if s == "[]" {
t.TemplateCategory = nil
return nil
}
var category TemplateCategory
if err := json.Unmarshal(b, &category); err != nil {
return err
}
t.TemplateCategory = &category
return nil
}
template.CategoryInfo.CategoryInfo
. Как сделать так, чтобы у меня в template.CategoryInfo был либо указатель на структуру, либо просто nil, а не &{nil}
? package main
import (
"encoding/json"
"fmt"
"log"
)
type TemplateCategory struct {
ID int `json:"id"`
Name string `json:"name"`
}
type Template struct {
Name string `json:"name"`
CategoryInfo *TemplateCategory `json:"category_info"`
}
func (t *Template) UnmarshalJSON(b []byte) error {
var result map[string]interface{}
if err := json.Unmarshal(b, &result); err != nil {
return err
}
if t == nil {
t = &Template{}
}
t.Name, _ = result[`name`].(string)
categoryInfo, isMap := result[`category_info`].(map[string]interface{})
if isMap {
t.CategoryInfo = &TemplateCategory{}
t.CategoryInfo.ID, _ = categoryInfo[`id`].(int)
t.CategoryInfo.Name, _ = categoryInfo[`name`].(string)
}
return nil
}
func main() {
json1 := []byte(`{
"name": "Мой шаблон",
"category_info": {
"id": 109,
"name": "Тест"
}
}`)
json2 := []byte(`{
"name": "Мой шаблон",
"category_info": []
}`)
var data1 Template
err := json.Unmarshal(json1, &data1)
if err != nil {
log.Fatalf(`json1: %s`, err)
}
var data2 Template
err = json.Unmarshal(json2, &data2)
if err != nil {
log.Fatalf(`json2: %s`, err)
}
fmt.Printf("data1: %+v\n", data1)
fmt.Printf("data1.CategoryInfo: %+v\n\n", data1.CategoryInfo)
fmt.Printf("\n\ndata2: %+v\n", data2)
fmt.Printf("data2.CategoryInfo: %+v\n\n", data2.CategoryInfo)
}
package main
import (
"encoding/json"
"fmt"
)
type TemplateCategory struct {
ID int `json:"id"`
Name string `json:"name"`
}
type Template struct {
Name string `json:"name"`
CategoryInfoRaw *json.RawMessage `json:"category_info"`
CategoryInfo *TemplateCategory
}
func (t *Template) UnmarshalJSON(data []byte) error {
type template Template
if err := json.Unmarshal(data, (*template)(t)); err != nil {
return err
}
if t.CategoryInfoRaw == nil || string(*t.CategoryInfoRaw) == "[]" {
t.CategoryInfo = nil
} else {
if err := json.Unmarshal(*t.CategoryInfoRaw, &t.CategoryInfo); err != nil {
return err
}
}
return nil
}
func main() {
res := &Template{}
str1 := `{
"name": "Мой шаблон",
"category_info": {
"id": 109,
"name": "Тест"
}
}`
str2 := `{
"name": "Мой шаблон",
"category_info": []
}`
_ = json.Unmarshal([]byte(str1), res)
fmt.Printf("%+v\n", res)
fmt.Printf("%+v\n", res.CategoryInfo)
_ = json.Unmarshal([]byte(str2), res)
fmt.Printf("%+v", res)
}