当加载配置的时候,我们通常会将配置设置一个默认值,但是通常默认值不是Go中的空值,比如 服务的端口号:

type ServerConfig struct{
    Port uint
}

func main(){
    conf:=loadConfig()

    if conf.ServerConfig.Port==0{
        conf.ServerConfig.Port = 8080
    }
}

每次有一个值我们都需要增加一个if语句进行判断,当一个配置有很多的时候,初始化写起来可能就非常的繁琐。

tag

原理比较简单大概流程就是:

  1. 通过反射解析当前的结构体
  2. 查看当前字段的值时候为空值
  3. 如果为空,读取tag中的default,并初始化
  4. 不为空直接略过

这里给出使用方法:

Defaults

Enforce default values on struct fields.

type User struct {
 Name     string  `default:"Goku"`
 Power    float64 `default:"9000.01"`
}

var u User

err := defaults.Apply(&u)
if err != nil {
 log.Fatal("Uh oh: %v", err)
}

fmt.Print(u.Name)  // Goku
fmt.Print(u.Power) // 9000.01

Defaults are only applied to fields at their zero value.

type Config struct {
 Host  *string `default:"0.0.0.0"`
 Port  *int    `default:"8000"`
}

var cfg Config
json.Unmarshal([]byte(`{Host: "charm.sh"}`), &cfg)

if err := defaults.Apply(&cfg); err != nil {
 log.Fatal("Rats: %v", err)
}

fmt.Print(cfg.Host) // charm.sh
fmt.Print(cfg.Port) // 8000

Works well with JSON, Yaml, and so on.

type Config struct {
    Host  string `json:"host" default:"0.0.0.0"`
    Port  int    `json:"port" default:"8000"`
    Debug bool   `json:"debug" default:"true"`
}

Supported Types

The following types are supported:

stringboolintint8int16int32runeint64uintuint8uint16uint32uint64float32float64[]byte[]uint8

…as well as pointers to those types.

Embedded Structs

Embedded structs are supported. The following will parse as expected:

type GroceryList struct {
 Fruit struct {
  Bananas int `default:"8"`
  Pears   int `default:"12"`
 }
 Vegetables *struct {
  Artichokes    int `default:"4"`
  SweetPotatoes int `default:"16"`
 }
}
defaultnil

Runes and Int32s

runeint32"1"1'1'int3249
runeint32rune
// This works as expected...
type Cool struct {
 Fave32BitInteger int32 `default:"12"`
 FaveChar         rune  `default:"a"`
}

// ...but these will not.
type UhOh struct {
 FaveChar rune `default:"3"`  // this is a unicode ETX or ctrl+c
 FaveChar rune `default:"97"` // this is a unicode `a`
}

这个package本来是: github.com/charmbracelet/defaults 但是原地址无法访问