Go语言实现结构体初始化设置默认值
在Go语言中结构体原生语法是不支持设置默认值的,这就在很多场景中需要增加额外的步骤,去设置一些默认值。
自从 Go 1.18支持泛型后,再通过反射功能即可实现为结构体设置默认值。
原理也非常简单,只要将结构体的标签中设置一个Key,即可通过Key的值赋予对象的指定字段。
package main
import (
"fmt"
"reflect"
"strconv"
)
type Person struct {
Name string `df:"无名氏"`
Age int `df:"18"`
}
func main() {
// 实例化类并指定标签
p := NewClass(Person{}, "df")
// 结果:{无名氏 18}
fmt.Println(p)
}
// 实例化结构体
// 目前只能实现基本数据类型
func NewClass[T any](cls T, dfKey string) T {
rt := reflect.ValueOf(&cls).Elem()
vt := rt.Type()
for i := 0; i < rt.NumField(); i++ {
f := rt.Field(i)
tag, ok := vt.Field(i).Tag.Lookup(dfKey)
if ok {
switch f.Kind() {
case reflect.Bool:
i, _ := strconv.ParseBool(tag)
f.SetBool(i)
case reflect.String:
f.SetString(tag)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
i, _ := strconv.ParseInt(tag, 10, 64)
f.SetInt(i)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
i, _ := strconv.ParseUint(tag, 10, 64)
f.SetUint(i)
case reflect.Float32, reflect.Float64:
i, _ := strconv.ParseFloat(tag, 64)
f.SetFloat(i)
// 更多数据类型支持需要自己定义规则
}
}
}
return cls
}