main
Your Name 2024-07-02 21:48:33 +08:00
parent af01ec1951
commit d4aef966b6
3 changed files with 74 additions and 10 deletions

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -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)
}

View File

@ -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