course/ini_unmarshal/conf_ini.go

103 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package main
import (
"fmt"
"os"
"strings"
"reflect"
)
//定义结构体
type MysqlConfig struct {
Address string `ini:"address"`
Port int `ini:"port"`
Username string `ini:"username"`
Password string `ini:"password"`
}
type RedisConfig struct {
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"`
}
func Loadini(fileName string, data interface{}) (err error) {
//0.参数的校验,对函数中修改值,必须是结构体指针
t := reflect.TypeOf(data)
//v := reflect.ValueOf(data)
//校验指针类型
if t.Kind() != reflect.Ptr {
err = fmt.Errorf("data should be pointer")
return
}
//校验结构体类型由于是指针要用elem方法
if t.Elem().Kind() != reflect.Struct {
err = fmt.Errorf("data should be struct")
return
}
//1.读取文件
b, err := os.ReadFile(fileName) //读取文件拿到字节类型的数据
if err != nil {
return
}
lineSlice := strings.Split(string(b), "\r\n") //字节类型的数据按照换行符切分
fmt.Printf("%#v\n", lineSlice)
//var structName string
//2.一行一行的读取数据
for idx, line := range lineSlice {
//2.1如果是注释,就跳过
line = strings.TrimSpace(line)
if strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") {
continue
}
//2.2如果是[开头的就表示节section
if strings.HasPrefix(line, "[") {
//校验1 首尾的[]都需要存在
if line[0] != '[' || line[len(line)-1] != ']' {
err = fmt.Errorf("line:%d syntax error", idx+1)
return
}
//结之间能取到的内容比如redis或者mysql这个字符串
sectionName := strings.TrimSpace(line[1 : len(line)-1])
//校验2 []之间应该有内容
if len(sectionName) == 0 { //切片:左包含右不包含
err = fmt.Errorf("line:%d syntax error", idx+1)
return
}
//根据字符串sectionName到data中根据反射找到结构体
for i := 0; i < t.Elem().NumField(); i++ {
field := t.Elem().Field(i)
if field.Tag.Get("ini") == sectionName {
//找到对应的嵌套结构体
//structName = field.Name
break
}
}
} else {
//2.3如果不是[,就是=分割的键值对
}
}
return //
}
func main() {
var cfg Config
err := Loadini("./ini_unmarshal/config.ini", &cfg)
if err != nil {
fmt.Println("load ini error:", err)
return
}
fmt.Println(cfg)
}