我有一个包含4个字段的结构:
type Animal struct {
Name string
Age int
Zone int
}
我正在执行一个发布请求,发送一个json对象以将其解码为struct, json应该看起来像这样:
{
"Age":10,
"Name":"Lion",
"Zone":1,
}
我希望所有字段都为字段,但是每当我不填写所有字段并发送一些json之类的
{
"Age":10,
"Zone":1,
}
json.Decoder自动构建该Filed并将其设置为""
(该类型的值为零)而不是null。
如何设置空值或检查它是否为空并生成错误?
我希望结果为{Age:10, Zone:1, Name:null}
或至少会产生错误!
这是我用来将json转换为struct的代码
animalModel := Animal{}
err := json.NewDecoder(r.Body).Decode(&animalModel)
答案 0 :(得分:1)
您可以使用指针
type Animal struct {
Name *string
Age int
Zone int
}
或包裹
import "github.com/guregu/null"
type Animal struct {
Name null.String
Age int
Zone int
}
答案 1 :(得分:1)
string
不能为零。如果要区分字段null
和空值""
的缺失,则可以使用以下选项:
type Animal struct {
Name *string
}
缺点是您需要使用时间变量来设置此字段。
Unmarshaler
接口,并使用时间map[string]string
进行所需的检查并返回错误:type Animal struct {
Name string
}
func (a *Animal) UnmarshalJSON(data []byte) error {
m := map[string]interface{}{}
err := json.Unmarshal(data, &m)
if err != nil {
return err
}
// check if field is exist
name, exist := m["name"]
if !exist {
return fmt.Errorf("field 'name' should be present")
}
// check other fields...
// ...
// if all fields are ok, you can:
// 1. set fields from map items
a.Name = name
...
// 2. call Unmarshal
return json.Unmarshal(data, a)
}
这里的缺点是您需要“手动”检查每个字段。
go-swagger
或go-openapi
。这些工具使您能够使用声明性架构(OpenAPI)对JSON数据执行检查,可以轻松实现版本控制,发布API等。
当然,对于3字段结构,这是过度设计。