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

Go語言項(xiàng)目中使用Viper獲取配置信息詳解

 更新時間:2024年04月02日 08:15:24   作者:仍沫  
Viper是Go應(yīng)用的完整配置解決方案,它能處理所有類型的配置需求和配置格式,這篇文章主要介紹了Go項(xiàng)目中使用Viper獲取配置信息,需要的可以參考下

Viper是Go應(yīng)用的完整配置解決方案,它能處理所有類型的配置需求和配置格式,支持:

  • 設(shè)置默認(rèn)值。
  • 讀取JSON、TOML、YAML、HCL、envfile和Java屬性配置文件。
  • 實(shí)時觀察和重新讀取配置(可選)。
  • 讀取環(huán)境變量。
  • 從遠(yuǎn)程配置系統(tǒng)(etcd或Consul)讀取配置,并觀察其變化。
  • 從命令行標(biāo)志讀取配置。
  • 從緩沖區(qū)讀取配置。
  • 設(shè)置顯式值。

Viper的優(yōu)先級順序是:顯式調(diào)用Set > 命令行標(biāo)志 > 環(huán)境變量 > 配置文件 > 鍵/值 存儲(etcd或Consul) > 默認(rèn)值。

本文主要記錄從yaml文件、環(huán)境變量中獲取配置。

使用的go的版本和viper的版本如下:

go 1.20
github.com/spf13/viper v1.18.2

從配置文件中獲取配置

執(zhí)行以下指令初始化項(xiàng)目:

go mod init github.com/rengmo/practicego

執(zhí)行以下語句安裝viper包:

go get github.com/spf13/viper

創(chuàng)建yaml文件config/dev.yaml,內(nèi)容如下:

redis:
  host: localhost
  port: 6379
  user:     # 本地redis的用戶名為空
  password: abc123
  db: 0

創(chuàng)建Go文件infrastructure/config.go,內(nèi)容如下:

package config

import (
	"fmt"

	"github.com/spf13/viper"
)

func init() {
	// 設(shè)置配置文件的名字
	viper.SetConfigName("dev")
	// 設(shè)置文件的格式
	viper.SetConfigType("yaml")
	// 設(shè)置查找配置文件的路徑為當(dāng)前路徑 . 表示項(xiàng)目的工作目錄,也就是main.go同級的那個目錄
	viper.AddConfigPath("./config")

	// 讀取配置文件中的數(shù)據(jù)到viper中
	err := viper.ReadInConfig()
	if err != nil {
		panic(err)
	}
	// 從viper中獲取配置數(shù)據(jù)
	redisPort := viper.Get("redis.port")
	fmt.Printf("redisPort: %v \n", redisPort) // 打印結(jié)果:redisPort: 6379 
}

還可以使用GetInt()、GetString()等方法,獲取指定類型的數(shù)據(jù),viper.GetString("redis.port")就是獲取字符串類型的數(shù)據(jù)。

創(chuàng)建main.go文件,內(nèi)容如下:

package main

import (
	_ "github.com/rengmo/practicego/infrastructure"
)

func main() {

}

運(yùn)行代碼,會打印出獲取到的端口號。

	// 設(shè)置配置文件的名字
	viper.SetConfigName("dev")
	// 設(shè)置文件的格式
	viper.SetConfigType("yaml")
	// 設(shè)置查找配置文件的路徑為當(dāng)前路徑 . 表示項(xiàng)目的工作目錄,也就是main.go同級的那個目錄
	viper.AddConfigPath("./config")

換成:

// 設(shè)置配置文件的路徑
viper.SetConfigFile("./config/dev.yaml")

同樣能取到配置文件中的數(shù)據(jù)。

除了使用Get方法viper.Get("redis.port")獲取配置數(shù)據(jù),還可以將配置數(shù)據(jù)反序列化成Go對象。

func init() {
  ...
	var config *Config
	err = viper.Unmarshal(&config)
	if err != nil {
		panic(err)
	}
	redisConfig := config.Redis
	fmt.Printf("redisConfig %+v\n", redisConfig) 
  // 打印的結(jié)果:redisConfig {Host:localhost Port:6379 User: Password:abc123 DB:0}
}

type Config struct {
	Redis RedisConfig
}

type RedisConfig struct {
	Host     string
	Port     int
	User     string
	Password string
	DB       int
}

Viper對于配置項(xiàng)的鍵是不區(qū)分大小寫的,比如把yaml文件中的鍵改成首字母大寫:

Redis:
  Host: localhost
  Port: 6379

使用viper.Get("redis.port")一樣能獲取到配置的值,使用viper.Get("REDIS.PORT")同樣能獲取配置的值。

從環(huán)境變量中獲取配置

AutomaticEnv會檢查環(huán)境變量中是否有和已經(jīng)存在的鍵匹配的環(huán)境變量,如果有,就會把環(huán)境變量加載到viper中。

// AutomaticEnv makes Viper check if environment variables match any of the existing keys
// (config, default or flags). If matching env vars are found, they are loaded into Viper.
func AutomaticEnv() { v.AutomaticEnv() }

先在終端執(zhí)行指令添加環(huán)境變量: export env=PROD,然后在終端執(zhí)行go run .

光看這個函數(shù)名稱,是自動將環(huán)境變量添加到viper中的意思,那么執(zhí)行下面的語句應(yīng)該就能獲取環(huán)境變量,但是無效:

	viper.AutomaticEnv()
	env := viper.Get("env")
	fmt.Println("env: ", env) // env:  <nil>

根據(jù)函數(shù)注釋,需要確認(rèn)viper中是否已經(jīng)有對應(yīng)的鍵,那么執(zhí)行下面的語句應(yīng)該就能獲取環(huán)境變量,但是依然無效:

	viper.SetDefault("env", "DEV")
	viper.AutomaticEnv()
	env := viper.Get("env")
	fmt.Println("env: ", env) // env:  DEV

找了一下源碼,判斷鍵是否存在的地方使用了envkeys, exists := v.env[lcaseKey],而BindEnv方法中有設(shè)置v.env

func (v *Viper) BindEnv(input ...string) error {
	if len(input) == 0 {
		return fmt.Errorf("missing key to bind to")
	}

	key := strings.ToLower(input[0])

	if len(input) == 1 {
		v.env[key] = append(v.env[key], v.mergeWithEnvPrefix(key))
	} else {
		v.env[key] = append(v.env[key], input[1:]...)
	}

	return nil
}

所以需要這樣使用:

	viper.BindEnv("env", "DEV")
	viper.AutomaticEnv()
	env := viper.Get("env")
	fmt.Println("env: ", env) // env:  PROD

要注意在比較過程中,Viper會把key轉(zhuǎn)換成大寫字母與環(huán)境變量進(jìn)行比較,所以環(huán)境變量的名稱必須為大寫,不能這樣設(shè)置環(huán)境變量:export env=PROD,必須這樣設(shè)置環(huán)境變量:export ENV=PROD。

其他

如果是使用編輯器來運(yùn)行代碼,需要在編輯器中設(shè)置環(huán)境變量,我用的是VSCode編輯器,所以是在launch.json中添加了環(huán)境變量:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}",
            "env": {
                "env": "PROD"
            }
        }
    ]
}

序列化和反序列化時,可以使用 mapstructure指定鍵的名稱。

比如yaml文件內(nèi)容:

mysql:
  host: localhost
  port: 3306
  user: root
  password: 666666Aa_
  db_name: practicego

go文件內(nèi)容:

type Config struct {
	Redis    RedisConfig
	MySQL    MySQLConfig
	Priority string
}

type MySQLConfig struct {
	Host     string
	Port     int
	User     string
	Password string
	DBName   string `mapstructure:"db_name"`
}

func init() {
	viper.SetConfigFile("./config/dev.yaml")
	err := viper.ReadInConfig()
	if err != nil {
		panic(err)
	}
  
  var config *Config
	err = viper.Unmarshal(&config)
	if err != nil {
		panic(err)
	}
  
  mysqlConfig := config.MySQL
	fmt.Printf("mysqlConfig %+v\n", mysqlConfig)
}

以上就是Go語言項(xiàng)目中使用Viper獲取配置信息詳解的詳細(xì)內(nèi)容,更多關(guān)于Go Viper獲取配置信息的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入理解Go語言unsafe包

    深入理解Go語言unsafe包

    Go語言通過類型和內(nèi)存安全設(shè)計保障可靠性,但unsafe包允許底層內(nèi)存操作以實(shí)現(xiàn)性能優(yōu)化與特殊交互,適用于結(jié)構(gòu)體字段訪問、零拷貝轉(zhuǎn)換等場景,感興趣的可以了解一下
    2025-08-08
  • 舉例講解Go語言中函數(shù)的閉包使用

    舉例講解Go語言中函數(shù)的閉包使用

    這篇文章主要介紹了Go語言中函數(shù)的閉包使用示例,函數(shù)閉包c(diǎn)losure是編程語言中十分重要的特性,需要的朋友可以參考下
    2016-03-03
  • Go singleflight使用以及原理

    Go singleflight使用以及原理

    singleflight官方解釋其為:singleflight提供了一個重復(fù)的函數(shù)調(diào)用抑制機(jī)制。通俗的解釋其作用是,若有多個協(xié)程運(yùn)行某函數(shù)時,只讓一個協(xié)程去處理,然后批量返回。非常適合來做并發(fā)控制。常見用于緩存穿透的情況
    2023-01-01
  • golang實(shí)現(xiàn)并發(fā)控制的方法和技巧

    golang實(shí)現(xiàn)并發(fā)控制的方法和技巧

    golang 是一門支持并發(fā)的編程語言,它提供了 goroutine 和 channel 等強(qiáng)大的特性,讓我們可以輕松地創(chuàng)建和管理多個執(zhí)行單元,實(shí)現(xiàn)高效的任務(wù)處理,在本文中,我們將介紹一些 golang 的并發(fā)控制的方法和技巧,希望對你有所幫助
    2024-03-03
  • 一文詳解Golang中字符串的常見錯誤

    一文詳解Golang中字符串的常見錯誤

    這篇文章主要來和大家深入討論一下Golang?中的字符串,并查看一些不同的場景,以避免常見錯誤,對大家掌握golang有一定的幫助,需要的可以了解下
    2023-10-10
  • golang連接mysql數(shù)據(jù)庫操作使用示例

    golang連接mysql數(shù)據(jù)庫操作使用示例

    這篇文章主要為大家介紹了golang連接mysql數(shù)據(jù)庫操作使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • goland?導(dǎo)入github包報紅問題解決

    goland?導(dǎo)入github包報紅問題解決

    本文主要介紹了Go項(xiàng)目在GoLand中導(dǎo)入依賴標(biāo)紅問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • golang socket斷點(diǎn)續(xù)傳大文件的實(shí)現(xiàn)方法

    golang socket斷點(diǎn)續(xù)傳大文件的實(shí)現(xiàn)方法

    今天小編就為大家分享一篇golang socket斷點(diǎn)續(xù)傳大文件的實(shí)現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • golang 如何用反射reflect操作結(jié)構(gòu)體

    golang 如何用反射reflect操作結(jié)構(gòu)體

    這篇文章主要介紹了golang 用反射reflect操作結(jié)構(gòu)體的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 使用Go語言實(shí)現(xiàn)配置文件熱加載功能

    使用Go語言實(shí)現(xiàn)配置文件熱加載功能

    這篇文章主要介紹了使用Go語言實(shí)現(xiàn)配置文件熱加載功能,以及配置文件熱加載包的實(shí)現(xiàn)思路,需要的朋友可以參考下
    2018-03-03

最新評論

淄博市| 锦州市| 永修县| 苍梧县| 拉萨市| 绥芬河市| 长宁县| 景谷| 霍林郭勒市| 大田县| 宜阳县| 竹山县| 德州市| 肇庆市| 西昌市| 孝感市| 东宁县| 天津市| 台南市| 乌兰县| 蓝田县| 洱源县| 敦煌市| 思茅市| 钟祥市| 晋州市| 永福县| 尚志市| 高陵县| 临海市| 东港市| 南岸区| 寿宁县| 城市| 安仁县| 乌拉特后旗| 陆河县| 张家口市| 绥江县| 浦城县| 东莞市|