From d4aef966b6bceb746417fe7cfae4e856ca24b028 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 2 Jul 2024 21:48:33 +0800 Subject: [PATCH] over --- .idea/vcs.xml | 6 ++++ ini_unmarshal/conf_ini.go | 71 ++++++++++++++++++++++++++++++++++----- ini_unmarshal/config.ini | 7 +++- 3 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 .idea/vcs.xml diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ini_unmarshal/conf_ini.go b/ini_unmarshal/conf_ini.go index b4916ab..b48b057 100644 --- a/ini_unmarshal/conf_ini.go +++ b/ini_unmarshal/conf_ini.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "strconv" "strings" "reflect" @@ -18,21 +19,21 @@ type MysqlConfig struct { } type RedisConfig struct { - host string `ini:"host"` + Host string `ini:"host"` Port int `ini:"port"` Password string `ini:"password"` Database string `ini:"database"` } type Config struct { - RedisConfig `ini:"mysql"` - MysqlConfig `ini:"redis"` + MysqlConfig `ini:"mysql"` + RedisConfig `ini:"redis"` } func Loadini(fileName string, data interface{}) (err error) { //0.参数的校验,对函数中修改值,必须是结构体指针 t := reflect.TypeOf(data) - //v := reflect.ValueOf(data) + v := reflect.ValueOf(data) //校验指针类型 if t.Kind() != reflect.Ptr { err = fmt.Errorf("data should be pointer") @@ -51,11 +52,15 @@ func Loadini(fileName string, data interface{}) (err error) { lineSlice := strings.Split(string(b), "\r\n") //字节类型的数据按照换行符切分 fmt.Printf("%#v\n", lineSlice) - //var structName string + var structName string //2.一行一行的读取数据 for idx, line := range lineSlice { //2.1如果是注释,就跳过 line = strings.TrimSpace(line) + //校验:跳过空行 + if len(line) == 0 { + continue + } if strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") { continue } @@ -78,16 +83,64 @@ func Loadini(fileName string, data interface{}) (err error) { field := t.Elem().Field(i) if field.Tag.Get("ini") == sectionName { //找到对应的嵌套结构体 - //structName = field.Name - break + structName = field.Name + fmt.Printf("找到%s对应的嵌套结构体%s\n", sectionName, structName) } } } else { //2.3如果不是[,就是=分割的键值对 + //校验:不能不存在等号或者以等号开头 + if strings.Index(line, "=") == -1 || strings.HasPrefix(line, "=") { + err = fmt.Errorf("line:%d syntax error", idx+1) + return + } + //1.以等号分割这一行,等号左边是key,等号右边是value + + //2.根据structName去data里把对应的嵌套结构体取出 + subValue := v.Elem().FieldByName(structName) + subType := subValue.Type() + if subValue.Kind() != reflect.Struct { + err = fmt.Errorf("field:%s is not struct", structName) + return + } + //切分line这一行,左边是key 右边是value + key := strings.Split(line, "=")[0] + value := strings.Split(line, "=")[1] + + //3.遍历嵌套结构体的每一个字段,判断tag是不是等于key,如果等于key,给这个字段赋值 + + var fieldName string + for i := 0; i < subType.NumField(); i++ { + field := subType.Field(i) + if field.Tag.Get("ini") == key { + fieldName = field.Name + } + } + //根据fieldName取出 这个字段,对其赋值 + fieldObj := subValue.FieldByName(fieldName) + fmt.Println(fieldName, fieldObj.Type().Kind()) + switch fieldObj.Type().Kind() { + case reflect.String: + fieldObj.SetString(value) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + valueInt, err := strconv.ParseInt(value, 10, 64) + if err != nil { + err = fmt.Errorf("line:%d value:%s error", idx+1, value) + return err + } + fieldObj.SetInt(valueInt) + case reflect.Bool: + valueBool, err := strconv.ParseBool(value) + if err != nil { + err = fmt.Errorf("line:%d value:%s error", idx+1, value) + return err + } + fieldObj.SetBool(valueBool) + } } } - return // + return } @@ -98,5 +151,5 @@ func main() { fmt.Println("load ini error:", err) return } - fmt.Println(cfg) + fmt.Printf("%#v", cfg) } diff --git a/ini_unmarshal/config.ini b/ini_unmarshal/config.ini index caa7180..28a443e 100644 --- a/ini_unmarshal/config.ini +++ b/ini_unmarshal/config.ini @@ -1,4 +1,7 @@ ; mysql config + + + [mysql] address=1.2.3.4 port=3306 @@ -9,10 +12,12 @@ password=pass # [ #[ ] + + # redis config [redis] host=127.0.0.1 -port=6379 +port=6370 password=root database=0