Go struct tag 能否設置默認值?

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 的時候如何賦默認值呢?

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/WhY38EvLMrr0E48SNNU13A