最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

讀取Go項(xiàng)目中的配置文件的方法

 更新時(shí)間:2022年06月17日 15:05:11   作者:范閑  
本文主要介紹了讀取Go項(xiàng)目中的配置文件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Go語(yǔ)言提供了很簡(jiǎn)便的讀取json和yaml文件的api,我們可以很輕松將一個(gè)json或者yaml文件轉(zhuǎn)換成Go的結(jié)構(gòu)體,但是如果直接在項(xiàng)目中讀取配置文件,這種方式并不夠好。缺點(diǎn)如下:

實(shí)際開發(fā)中配置項(xiàng)在不同環(huán)境下,配置的值是不同的

上面的問(wèn)題可以通過(guò)不同的配置文件去決定在那個(gè)環(huán)境讀取那個(gè)配置文件,但是還有一個(gè)問(wèn)題就是實(shí)際開發(fā)中,配置項(xiàng)有些是相同的,有些是不同的,如果配置文件有一個(gè)主配置文件,里面存放的是不同環(huán)境相同的配置項(xiàng),還有一個(gè)跟隨環(huán)境的配置文件,里面存放的是不同環(huán)境的配置項(xiàng),然后讀取兩個(gè)配置文件后,做一個(gè)merge,這樣得到的結(jié)果就是總共的配置項(xiàng)信息。

有些配置項(xiàng)是必填的,有些配置項(xiàng)的值是一些特殊的值,比如,郵箱,手機(jī)號(hào),IP信息等

來(lái)看看gonfig是怎么解決這個(gè)問(wèn)題的

  • 安裝gonfig
go get github.com/xiao-ren-wu/gonfig
  • 項(xiàng)目中新建配置目錄,并編寫對(duì)應(yīng)配置文件,在配置目錄同級(jí)目錄添加讀取配置文件的go文件

conf.yaml文件中存放的是通用的配置,conf-{{active}}.yaml中存放不同環(huán)境不同的配置信息。

conf
   |-conf.yaml
   |-conf-dev.yaml
   |-conf-prod.yaml
   |config.go
  • 利用go:embed將配置文件載入到內(nèi)存,調(diào)用gonfig.Unmarshal讀取配置文件
package config

import (
   "model"
   "github.com/xiao-ren-wu/gonfig"
   "embed"
)

//go:embed *.yaml
var confDir embed.FS

// 我們配置文件的配置struct
type AppConf struct {
	AppName string `yaml:"app-name" json:"app-name"`
	DB      DBConf `yaml:"db" json:"db"`
}

type DBConf struct {
	Username string `yaml:"username" json:"username"`
	Password string `yaml:"password" json:"password"`
}

var conf Conf

func Init() {
   if err := gonfig.Unmarshal(confDir, &conf); err != nil {
      panic(err)
   }
}

func GetConf() *Conf {
   return &conf
}

這樣就完成了項(xiàng)目中配置文件的讀取,是不是很簡(jiǎn)單? 此時(shí)讀到的配置形式是conf-{{profile}}.yamlconf.yaml的總和,如果conf-{{profile}}.yaml中定義的屬性和conf.yaml相同,那么會(huì)以conf-{{profile}}.yaml為準(zhǔn)

約定

gonfigAPI的簡(jiǎn)潔性的原因是因?yàn)楸澈笞隽撕芏嗉s束,只有符合約束的配置才能被成功讀取,具體的約束條件如下:

  • gonfig.Unmarshal會(huì)默認(rèn)讀取文件名稱有前綴conf的文件

  • 通過(guò)環(huán)境變量profile作為環(huán)境名稱,如果沒有配置,默認(rèn)dev。

  • 程序會(huì)尋找conf.yaml作為主配置文件,conf-{{profile}}.yaml作為環(huán)境特有配置文件,然后對(duì)文件內(nèi)容進(jìn)行合并

  • 如果conf-{{profile}}.yaml中的屬性和conf.yaml中屬性都有定義,那么會(huì)以conf-{{profile}}.yaml為準(zhǔn)。

根據(jù)項(xiàng)目定制化配置文件

gonfig.Unmarshal的函數(shù)簽名func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error 提供很多配置項(xiàng),供用戶定制化需求,具體的配置信息如下:

  • 更改配置文件名稱前綴FilePrefix(prefix string)

  • 更改讀取配置文件類型UnmarshalWith(uType UnmarshalType)

  • 更改讀取的環(huán)境變量名稱ProfileUseEnv(envName, defaultProfile string)

  • 自定義設(shè)置profileProfileFunc(f func() string)

原理篇

gonfig的實(shí)現(xiàn)也很簡(jiǎn)單,核心的源碼如下:

func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error {
	if v != nil && reflect.ValueOf(v).Kind() != reflect.Ptr {
		return gonfig_error.ErrNonPointerArgument
	}

	var cs = &confStruct{
		confPrefix:      "conf",
		envName:         "profile",
		defaultEnvValue: "dev",
		unmarshalType:   Yaml,
	}
	cs.activeProfileFunc = func() string {
		return getActiveProfile(cs.envName, cs.defaultEnvValue)
	}

	for _, op := range ops {
		op(cs)
	}

	cs.profileActive = cs.activeProfileFunc()

	if err := loadConf(confDir, cs); err != nil {
		return err
	}

	// copy val
	v1 := reflect.New(reflect.TypeOf(v).Elem()).Interface()

	if err := fileUnmarshal(cs.activeConfRaw, v1, cs.unmarshalType); err != nil {
		return err
	}

	if len(cs.masterConfRaw) == 0 {
		return gonfig_error.MasterProfileConfNotSetError
	}

	if err := fileUnmarshal(cs.masterConfRaw, v, cs.unmarshalType); err != nil {
		return err
	}

	return mergo.Merge(v, v1, mergo.WithOverride)
}

大概的原理就是復(fù)制了一份用戶傳給函數(shù)的結(jié)構(gòu)體v1,結(jié)構(gòu)體v1和v分別用于接收conf-{{profile}}.yaml中的屬性和conf.yaml的配置信息,然后通過(guò)調(diào)用三方開源庫(kù)mergo對(duì)兩個(gè)結(jié)構(gòu)體的屬性做一個(gè)merge。

這就是關(guān)于gonfig的全部?jī)?nèi)容啦~~~

github地址是:https://github.com/xiao-ren-wu/gonfig

到此這篇關(guān)于讀取Go項(xiàng)目中的配置文件的方法的文章就介紹到這了,更多相關(guān)Go讀取配置文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go設(shè)計(jì)模式之模板方法模式講解和代碼示例

    Go設(shè)計(jì)模式之模板方法模式講解和代碼示例

    模版方法是一種行為設(shè)計(jì)模式, 它在基類中定義了一個(gè)算法的框架, 允許子類在不修改結(jié)構(gòu)的情況下重寫算法的特定步驟,本文將通過(guò)代碼示例給大家詳細(xì)的介紹一下Go模板方法模式,需要的朋友可以參考下
    2023-08-08
  • Go項(xiàng)目在linux服務(wù)器的部署詳細(xì)步驟

    Go項(xiàng)目在linux服務(wù)器的部署詳細(xì)步驟

    在今天的軟件開發(fā)中,使用Linux作為操作系統(tǒng)的比例越來(lái)越高,而Golang語(yǔ)言則因?yàn)槠涓咝?、?jiǎn)潔和并發(fā)性能等特點(diǎn),也被越來(lái)越多的開發(fā)者所青睞,這篇文章主要給大家介紹了關(guān)于Go項(xiàng)目在linux服務(wù)器的部署詳細(xì)步驟,需要的朋友可以參考下
    2023-09-09
  • Go方法接收者值接收者與指針接收者詳解

    Go方法接收者值接收者與指針接收者詳解

    這篇文章主要為大家介紹了Go方法接收者值接收者與指針接收者詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Go語(yǔ)言利用泛型封裝常見的Map操作

    Go語(yǔ)言利用泛型封裝常見的Map操作

    Go?語(yǔ)言在?1.18?版本中引入了泛型,這是?Go?語(yǔ)言發(fā)展的一個(gè)重要里程碑,它極大地增強(qiáng)了語(yǔ)言的表達(dá)能力和靈活性,本文將通過(guò)泛型實(shí)現(xiàn)封裝常見的Map操作,感興趣的可以了解下
    2025-02-02
  • Go語(yǔ)言的方法接受者類型用值類型還是指針類型?

    Go語(yǔ)言的方法接受者類型用值類型還是指針類型?

    這篇文章主要介紹了Go語(yǔ)言的方法接受者類型用值類型還是指針類型?本文還同時(shí)講解了關(guān)于接受者的命名方式,需要的朋友可以參考下
    2014-10-10
  • Go 自定義package包設(shè)置與導(dǎo)入操作

    Go 自定義package包設(shè)置與導(dǎo)入操作

    這篇文章主要介紹了Go 自定義package包設(shè)置與導(dǎo)入操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • Go語(yǔ)言編譯時(shí)為exe添加圖標(biāo)和屬性信息的方法

    Go語(yǔ)言編譯時(shí)為exe添加圖標(biāo)和屬性信息的方法

    在使用Go語(yǔ)言開發(fā)應(yīng)用程序時(shí),有個(gè)非常方便的地方就是編譯得到的可執(zhí)行文件可以不依賴任何動(dòng)態(tài)鏈接庫(kù)、并且不需要任何運(yùn)行環(huán)境即可運(yùn)行,本文給大家介紹Go編譯時(shí)為exe添加圖標(biāo)和屬性信息的方法,需要的朋友可以參考下
    2023-09-09
  • Go通過(guò)goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程

    Go通過(guò)goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程

    多協(xié)程文件上傳是指利用多線程或多協(xié)程技術(shù),同時(shí)上傳一個(gè)或多個(gè)文件,以提高上傳效率和速度,本文給大家介紹了Go通過(guò)goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程,需要的朋友可以參考下
    2024-05-05
  • Go并發(fā)編程中sync/errGroup的使用

    Go并發(fā)編程中sync/errGroup的使用

    本文主要介紹了Go并發(fā)編程中sync/errGroup的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Golang接口的定義與空接口及斷言的使用示例

    Golang接口的定義與空接口及斷言的使用示例

    在?Golang?中,接口是一種類型,它是由一組方法簽名組成的抽象集合。這篇文章主要為大家介紹了Golang接口的具體使用,希望對(duì)大家有所幫助,空接口是特殊形式的接口類型,普通的接口都有方法,而空接口沒有定義任何方法口,也因此,我們可以說(shuō)所有類型都至少實(shí)現(xiàn)了空接口
    2023-04-04

最新評(píng)論

宽甸| 东乌珠穆沁旗| 西贡区| 东平县| 东乡族自治县| 丰台区| 庐江县| 凤冈县| 乌鲁木齐县| 开远市| 萝北县| 黎川县| 定陶县| 朝阳区| 金阳县| 上林县| 隆化县| 衡水市| 南充市| 彰武县| 锡林浩特市| 曲沃县| 成安县| 灵丘县| 辰溪县| 桐柏县| 兰溪市| 明水县| 河津市| 曲松县| 韩城市| 永川市| 玉山县| 名山县| 肥西县| 辛集市| 礼泉县| 察哈| 三台县| 舒城县| 峡江县|