struct tag默认值
1. 需求背景
有时候gopher在marshal一个struct到json的时候,想要struct某些属性在没有值的情况下有默认值,但是按照现在marshar的作用下不会给struct的属性赋默认值,所以为了解决这个特殊需求,我们应该按照以下方案来解决。
2. 解决方案
利用反射,因为通过反射,我们可以拿到tag属性,进而对默认字段做赋值操作
先看一段代码:
type test struct {
Name string `json:"name"`
Addr string `json:"addr" default:"localhost"`
Port uint `json:"port" default:"8080"`
}
func MarshalJson(i interface{}) ([]byte, error) {
typeof := reflect.TypeOf(i)
valueof := reflect.ValueOf(i)
for i := 0; i < typeof.Elem().NumField(); i++ {
if valueof.Elem().Field(i).IsZero() {
def := typeof.Elem().Field(i).Tag.Get("default")
if def != "" {
switch typeof.Elem().Field(i).Type.String() {
case "int":
result, _ := strconv.Atoi(def)
valueof.Elem().Field(i).SetInt(int64(result))
case "uint":
result, _ := strconv.ParseUint(def, 10, 64)
valueof.Elem().Field(i).SetUint(result)
case "string":
valueof.Elem().Field(i).SetString(def)
}
}
}
}
return json.Marshal(i)
}
func main() {
t := &test{
Name: "test server",
}
data, err := MarshalJon(t)
if err != nil {
panic(err)
}
fmt.Println(string(data))
}
结果:
{"name":"test server","addr":"localhost","port":8080}
3. 小结
其实在解析struct的时候golang本身已经为struct的属性按照类型赋默认值了,但是这个默认值在没有办法满足我们的需求的时候,这个时候就需要造轮子,别怕麻烦,解决问题才是王道。大家想想unmarshal的时候如何赋默认值呢?
- END -