beego config模块源码分析笔记一 - Go语言中文社区

beego config模块源码分析笔记一


这个包有以下这些内容:


image.png

第一个文件config.go,先分析这个文件内容

向开发者提供的内容:
(1)常量
(2)变量
(3)接口
(4)结构体
(5)函数

一、常量
二、变量
三、接口
1)type Configer interface

type Configer interface {
    Set(key, val string) error
    String(key string) string 
    Strings(key string) []string
    Int(key string) (int, error)
    Int64(key string) (int64, error)
    Bool(key string) (bool, error)
    Float(key string) (float64, error)
    DefaultString(key string, defaultVal string) string
    DefaultStrings(key string, defaultVal []string) []string
    DefaultInt(key string, defaultVal int) int
    DefaultInt64(key string, defaultVal int64) int64
    DefaultBool(key string, defaultVal bool) bool
    DefaultFloat(key string, defaultVal float64) float64
    DIY(key string) (interface{}, error)
    GetSection(section string) (map[string]string, error)
    SaveConfigFile(filename string) error
}

2)type Config interface

type Config interface {
    Parse(key string) (Configer, error)
    ParseData(data []byte) (Configer, error)
}

四、结构体
五、函数
1)func Register(name string, adapter Config)
注册config适配器,将注册的适配器存储在内部适配器变量adapters中

var adapters = make(map[string]Config)

func Register(name string, adapter Config) {
    if adapter == nil {
        panic("config: Register adapter is nil")
    }
    if _, ok := adapters[name]; ok {
        panic("config: Register called twice for adapter " + name)
    }
    adapters[name] = adapter
}

2)func NewConfig(adapterName, filename string) (Configer, error)

func NewConfig(adapterName, filename string) (Configer, error) {
    adapter, ok := adapters[adapterName]
    if !ok {
        return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName)
    }
    return adapter.Parse(filename)
}

3)func NewConfigData(adapterName string, data []byte) (Configer, error)

func NewConfigData(adapterName string, data []byte) (Configer, error) {
    adapter, ok := adapters[adapterName]
    if !ok {
        return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName)
    }
    return adapter.ParseData(data)
}

4)func ExpandValueEnvForMap(m map[string]interface{}) map[string]interface{}
ExpandValueEnvForMap和ExpandValueEnv结合实现map[string]interface{} 将对应的环境变量名转为值

func ExpandValueEnvForMap(m map[string]interface{}) map[string]interface{} {
    for k, v := range m {
        switch value := v.(type) {
        case string:
            m[k] = ExpandValueEnv(value)
        case map[string]interface{}:
            m[k] = ExpandValueEnvForMap(value)
        case map[string]string:
            for k2, v2 := range value {
                value[k2] = ExpandValueEnv(v2)
            }
            m[k] = value
        }
    }
    return m
}

5)func ExpandValueEnv(value string) (realValue string)

func ExpandValueEnv(value string) (realValue string) {
    realValue = value

    vLen := len(value)
    // 3 = ${}
    if vLen < 3 {
        return
    }
    // Need start with "${" and end with "}", then return.
    if value[0] != '$' || value[1] != '{' || value[vLen-1] != '}' {
        return
    }

    key := ""
    defaultV := ""
    // value start with "${"
    for i := 2; i < vLen; i++ {
        if value[i] == '|' && (i+1 < vLen && value[i+1] == '|') {
            key = value[2:i]
            defaultV = value[i+2 : vLen-1] // other string is default value.
            break
        } else if value[i] == '}' {
            key = value[2:i]
            break
        }
    }

    realValue = os.Getenv(key)
    if realValue == "" {
        realValue = defaultV
    }

    return
}

6)func ParseBool(val interface{}) (value bool, err error)
解析interface{}成bool类型

func ParseBool(val interface{}) (value bool, err error) {
    if val != nil {
        switch v := val.(type) {
        case bool:
            return v, nil
        case string:
            switch v {
            case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "Y", "y", "ON", "on", "On":
                return true, nil
            case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "N", "n", "OFF", "off", "Off":
                return false, nil
            }
        case int8, int32, int64:
            strV := fmt.Sprintf("%d", v)
            if strV == "1" {
                return true, nil
            } else if strV == "0" {
                return false, nil
            }
        case float64:
            if v == 1.0 {
                return true, nil
            } else if v == 0.0 {
                return false, nil
            }
        }
        return false, fmt.Errorf("parsing %q: invalid syntax", val)
    }
    return false, fmt.Errorf("parsing <nil>: invalid syntax")
}

7)func ToString(x interface{}) string
将interface{}转成string

func ToString(x interface{}) string {
    switch y := x.(type) {

    // Handle dates with special logic
    // This needs to come above the fmt.Stringer
    // test since time.Time's have a .String()
    // method
    case time.Time:
        return y.Format("A Monday")

    // Handle type string
    case string:
        return y

    // Handle type with .String() method
    case fmt.Stringer:
        return y.String()

    // Handle type with .Error() method
    case error:
        return y.Error()

    }

    // Handle named string type
    if v := reflect.ValueOf(x); v.Kind() == reflect.String {
        return v.String()
    }

    // Fallback to fmt package for anything else like numeric types
    return fmt.Sprint(x)
}
版权声明:本文来源简书,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.jianshu.com/p/96b34782ca40
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-01-12 11:59:06
  • 阅读 ( 880 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢