前言
由于在Golang中各种int类型的默认值是0,这就导致了在Web应用中可能会遇到一个请求里面的数值类型传递0和不传递该参数,这两种情况下Unmarshal到结构体中的该字段结果0,那么要怎么判断前端是否传递了该参数呢?
方案一:值类型改成指针类型
type Demo struct {
Date string `json:"date"`
Count *int32 `json:"count"`
}
这种方式显而易见,前端传端null,指针接受到的值就是nil,从而避免了不传该参数的情况。但是这么做会导致其他的情况,比如多数ORM组件是不支持指针类型的元素做主键。
改进
新建一个新的struct,使用一个这个新的struct代替原来的类型
type NullInt64 struct {
Int64 int64
Valid bool // Valid is true if Int64 is not NULL
}
然后给这个struct实现解析json时需要的Unmarshal那一套方法。
方案二:交给值校验的Package
如果不让为空可以直接报错的场景下,可以在结构体上用tag描述校验规则,使用第三方的包来做值校验。
例如Gin中默认使用的Go-Validator就是值校验非常好用的框架,只需要在tag中指定required标记。
type Demo struct {
Date string `json:"date"`
Count int32 `json:"count",validator:"required"`
}
方案三:对承载 Unmarsha 结果的对象设定一个不可能的默认值
这种方法简单粗暴,直接上代码。
var jsonBlob = []byte(`[{"Name": "Platypus", "Order": "Monotremata"}]`)
type Animal struct {
Name string
Order string
ID int
}
animals := &Animal{ID: -9999}
err := json.Unmarshal(jsonBlob, animals)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", animals)