欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

獲取Golang環(huán)境變量的三種方式小結(jié)

 更新時(shí)間:2024年11月14日 11:55:18   作者:夢(mèng)想畫家  
本文介紹了Golang中獲取環(huán)境變量的三種方式,包含使用Viper包、GoDotEnv包和os包,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

環(huán)境變量是應(yīng)用軟件參數(shù)配置的最佳方式,可以定義系統(tǒng)級(jí),如開發(fā)、測(cè)試以及生成階段。配置參數(shù)主要有數(shù)據(jù)庫(kù)配置、第三方url等。因此環(huán)境變量對(duì)于開發(fā)和部署應(yīng)用至關(guān)重要。

環(huán)境變量和配置文件

shell 編程中從文件讀變量相對(duì)容易,只需要source包括環(huán)境變量的配置文件,就可以訪問所有這些變量。golang必須依賴一些模塊從文件中讀變量。本文內(nèi)容包括:

  • 如何通過文件聲明環(huán)境變量
  • 如何從文件讀取環(huán)境變量
  • 當(dāng)變量未定義或空,如何設(shè)置缺省值
  • 如果從系統(tǒng)讀取環(huán)境變量
  • 如何檢查環(huán)境變量被定義或非空

當(dāng)容器化部署應(yīng)用(cloud, Kubernetes, 或Docker)至測(cè)試和生產(chǎn)環(huán)境時(shí),環(huán)境變量角色非常重要,它可以很容易覆蓋缺省配置。golang訪問環(huán)境變量常用方法有三種:

  • Viper 包
  • godotenv 包
  • os 包

我們?cè)谑纠?xiàng)目中創(chuàng)建配置文件app.env文件,用于設(shè)置預(yù)定環(huán)境變量的缺省值。

創(chuàng)建環(huán)境變量配置文件必須遵守一些規(guī)則,否則golang可能不會(huì)識(shí)別變量值:

所有變量必須在單獨(dú)行中聲明
區(qū)分大小寫的變量名應(yīng)該使用大寫命名,單詞應(yīng)該用下劃線分隔,舉例:DB_HOST
變量值跟在變量名稱后面使用等號(hào)分割,舉例:DB_HOST=localhost
變量值不用雙引號(hào),舉例: DB_HOST=”localhost”
注釋不應(yīng)該與變量在一行,舉例:

# depends with database ports mysql,mongodb,postgres etc
DB_PORT=5432

舉例,app.env 文件:

# sample app.env
# environment can be test,production,testing
APP_ENV=development
# username
DB_USER=postgres
# secure password
DB_PASS=pass
# app version not set
APP_VERSION=
#listening to any address
SERVER_ADDRESS=0.0.0.0:8080
# host value
DB_HOST=localhost
#depends with database mysql,mongodb,postgres etc
DB_PORT=5432

使用Viper包從配置文件中讀環(huán)境變量

這是一個(gè)環(huán)境變量管理工具包,可以從環(huán)境變量或配置文件中讀變量值。通過下面命令安裝包:

go get github.com/spf13/viper

示例1

首先定義結(jié)構(gòu)體,用于全局保存配置文件中的環(huán)境變量。

type Config struct {
	AppEnv        string `mapstructure:"APP_ENV"`
	DBUser        string `mapstructure:"DB_USER"`
	DBPass        string `mapstructure:"DB_PASS"`
	DBHost        string `mapstructure:"DB_HOST"`
	DBPort        string `mapstructure:"DB_PORT"`
	DBDriver      string `mapstructure:"DB_DRIVER"`
	AppVersion    string `mapstructure:"APP_VERSION"`
	ServerAddress string `mapstructure:"SERVER_ADDRESS"`
}

下面定義函數(shù)加載配置文件:

func LoadConfig(path string) (config Config, err error) {
	// Read file path
	viper.AddConfigPath(path)

	// set config file and path
	viper.SetConfigName("app")
	viper.SetConfigType("env")

	// watching changes in app.env
	viper.AutomaticEnv()

	// reading the config file
	err = viper.ReadInConfig()
	if err != nil {
		return
	}

	err = viper.Unmarshal(&config)
	return
}

完整代碼如下:

package main

import (
	"fmt"
	"log"

	"github.com/spf13/viper"
)

// Config stores all configuration of the application.
// The values are read by viper from a config file or environment variable.
type Config struct {
	AppEnv        string `mapstructure:"APP_ENV"`
	DBUser        string `mapstructure:"DB_USER"`
	DBPass        string `mapstructure:"DB_PASS"`
	DBHost        string `mapstructure:"DB_HOST"`
	DBPort        string `mapstructure:"DB_PORT"`
	DBDriver      string `mapstructure:"DB_DRIVER"`
	AppVersion    string `mapstructure:"APP_VERSION"`
	ServerAddress string `mapstructure:"SERVER_ADDRESS"`
}

// LoadConfig reads configuration from file or environment variables.
func LoadConfig(path string) (config Config, err error) {
	// Read file path
	viper.AddConfigPath(path)
	// set config file and path
	viper.SetConfigName("app")
	viper.SetConfigType("env")
	// watching changes in app.env
	viper.AutomaticEnv()
	// reading the config file
	err = viper.ReadInConfig()
	if err != nil {
		return
	}

	err = viper.Unmarshal(&config)
	return
}

func main() {
	// load app.env file data to struct
	config, err := LoadConfig(".")

	// handle errors
	if err != nil {
		log.Fatalf("can't load environment app.env: %v", err)
	}

	fmt.Printf(" -----%s----\n", "Reading Environment variables Using Viper package")
	fmt.Printf(" %s = %v \n", "Application_Environment", config.AppEnv)
	// not defined
	fmt.Printf(" %s = %s \n", "DB_DRIVE", dbDrive)
	fmt.Printf(" %s = %s \n", "Server_Listening_Address", config.ServerAddress)
	fmt.Printf(" %s = %s \n", "Database_User_Name", config.DBUser)
	fmt.Printf(" %s = %s \n", "Database_User_Password", config.DBPass)

}

輸出結(jié)果:

$ go run main.go
 ------Reading Environment variables Using Viper package----------
 Application_Environment = development 
 Server_Listening_Address = 0.0.0.0:8080 
 Database_User_Name = postgres 
 Database_User_Password = pass

示例2

有時(shí)環(huán)境變量可能未設(shè)置,這樣代碼可能會(huì)出錯(cuò),我們可以使用下面方法定義缺省值:

viper.SetDefault:

下面示例代碼定義函數(shù),如果變量未空或未定義,則返回缺省值:

package main

import (
	"fmt"

	"github.com/spf13/viper"
)

//Function to read an environment or return a default value
func getEnvValue(key string, defaultValue string) string {

	// Get file path
	viper.SetConfigFile("app.env")
	//read configs and handle errors
	err := viper.ReadInConfig()
	if err != nil {
		fmt.Println(err)
	}
	value := viper.GetString(key)
	if value != "" {
		return value
	}
	return defaultValue
}
func main() {
	// reading environments variable using the viper
	appEnv := getEnvValue("APP_ENV", "defaultEnvtesting")
	// not set in our app.env
	appVersion := getEnvValue("APP_VERSION", "1")
	dbPass := getEnvValue("DB_PASS", "1234")
	dbUser := getEnvValue("DB_USER", "goLinux_DB")
	serverAddress := getEnvValue("SERVER_ADDRESS", "127.0.0.1:8080")

	fmt.Printf(" ------%s-----\n", "Reading Environment variables Using Viper package")
	fmt.Printf(" %s = %s \n", "Application_Environment", appEnv)
	fmt.Printf(" %s = %s \n", "Application_Version", appVersion)
	fmt.Printf(" %s = %s \n", "Server_Listening_Address", serverAddress)
	fmt.Printf(" %s = %s \n", "Database_User_Name", dbUser)
	fmt.Printf(" %s = %s \n", "Database_User_Password", dbPass)
}

輸出結(jié)果:

$ go run main.go
 ---Reading Environment variables Using Viper package--------
 Application_Environment = development 
 Application_Version = 1 
 Server_Listening_Address = 0.0.0.0:8080 
 Database_User_Name = postgres 
 Database_User_Password = pass

使用GoDotEnv包從配置文件中讀環(huán)境變量

GoDotEnv包功能與viper包類似,但使用godotenv.Load()函數(shù)加載app.env文件,它接收文件名作為輸入,返回應(yīng)用上下文中的值。實(shí)現(xiàn)下面命令安裝包:

 go get github.com/joho/godotenv

Load方法可以傳入文件名稱,舉例:godotenv.Load("app.env")。
有時(shí).env文件位于項(xiàng)目根目錄,則可以直接載入,無需傳入?yún)?shù):godotenv.Load("app.env)godotenv還支持一次加載多個(gè)配置文件:

_ = godotenv.Load("app.env", "k8s_app.env")

并且還支持YAML文件作為輸入:

// app.YAML
APP_ENV: Development
SERVER_ADDRESS: 0.0.0.0:8080

下面看一個(gè)完整實(shí)例:

// main.go
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/joho/godotenv"
)

// Function to read an environment or return a default value
func getEnvValue(key string, defaultValue string) string {
	if value, ok := os.LookupEnv(key); ok && value != "" {
		return value
	}
	return defaultValue
}

func main() {
	// load app.env file
	err := godotenv.Load("app.env")
	//handle errors
	if err != nil {
		log.Fatalf("can't load environment app.env: %v", err)
	}

	// reading environments variable from the app context
	appEnv := getEnvValue("APP_ENV", "defaultEnvtesting")

	// not defined in our app.env
	appVersion := getEnvValue("APP_VERSION", "1")
	dbPass := getEnvValue("DB_PASS", "1234")

	// DB_NAME not defined in app env
	dbName := getEnvValue("DB_NAME", "goLinux_DB")
	dbUser := getEnvValue("DB_USER", "goLinux_DB")
	serverAddress := getEnvValue("SERVER_ADDRESS", "127.0.0.1:8080")

	fmt.Printf(" ----%s---\n", "Reading Environment variables Using GoDotEnv package ")
	fmt.Printf(" %s = %s \n", "Application_Environment", appEnv)
	fmt.Printf(" %s = %s \n", "Application_Version", appVersion)
	fmt.Printf(" %s = %s \n", "Server_Listening_Address", serverAddress)
	fmt.Printf(" %s = %s \n", "Database_User_Name", dbUser)
	fmt.Printf(" %s = %s \n", "Database_User_Password", dbPass)
	fmt.Printf(" %s = %s \n", "Database_Name", dbName)

}

輸出結(jié)果:

$ go run main.go   
              
 -----Reading Environment variables Using GoDotEnv package-----
 Application_Environment = development 
 Application_Version = 1 
 Server_Listening_Address = 0.0.0.0:8080 
 Database_User_Name = postgres 
 Database_User_Password = pass 
 Database_Name = goLinux_DB

使用os包從配置文件中讀環(huán)境變量

使用os.Setenv()設(shè)置環(huán)境變量

os.Setenv(key,value) 接收兩個(gè)輸入?yún)?shù),一個(gè)為key,另一個(gè)是環(huán)境變量值。
語(yǔ)法如下:

err := os.Setenv(key, value)
if err != nil {
	fmt.Printf("error will setting the environment value: %s", err)
}

舉例,設(shè)置COLOUR=BLUE:

err := os.Setenv(COLOUR, BLUE)
if err != nil {
	fmt.Printf("error will setting the environment value: %s", err)
}

使用os.Getenv()讀系統(tǒng)環(huán)境變量

os.Getenv接收key,舉例,下面代碼獲取環(huán)境變量PATH的值:

// main.go
package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("supported paths in my shell: ", os.Getenv("PATH"))
}

使用os.LookupEnv()讀系統(tǒng)環(huán)境變量

os.Getenv()的缺點(diǎn)是無錯(cuò)誤返回key。對(duì)于需要增加額外檢查是否存在,則需要使用os.LookupEnv(),其返回值中包括布爾變量用于表示key是否存在。舉例:

// main.go
package main

import (
	"fmt"
	"log"
	"os"
)

func main() {

	path, ok := os.LookupEnv("PATH123")
	if !ok {
		log.Fatalln(path + " variable is not defined")
	}
	fmt.Println(path)
}

使用os.UnsetEvn()取消設(shè)置環(huán)境變量

os.UnsetEvn() 刪除或取消定義任何系統(tǒng)環(huán)境變量。注意,這只會(huì)暫時(shí)取消當(dāng)前終端的變量設(shè)置。舉例:

// main.go
package main

import (
	"fmt"
	"os"
)

func main() {
	
	os.Setenv("MYUSER", "TestUser")
	// Before unsetting the variable
	out, _ := os.LookupEnv("MYUSER")
	fmt.Println("BEFORE: " + out)

	// Unset the variable
	os.Unsetenv("MYUSER")

	// After unsetting the variable
	out, _ = os.LookupEnv("MYUSER")
	fmt.Println("AFTER: " + out)
}

總結(jié)

到此這篇關(guān)于獲取Golang環(huán)境變量的三種方式小結(jié)的文章就介紹到這了,更多相關(guān)Golang獲取環(huán)境變量?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解讀rand.Seed(time.Now().UnixNano())的作用及說明

    解讀rand.Seed(time.Now().UnixNano())的作用及說明

    這篇文章主要介紹了關(guān)于rand.Seed(time.Now().UnixNano())的作用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2023-03-03
  • Windows下CMD執(zhí)行Go出現(xiàn)中文亂碼的解決方法

    Windows下CMD執(zhí)行Go出現(xiàn)中文亂碼的解決方法

    本文主要介紹了Windows下CMD執(zhí)行Go出現(xiàn)中文亂碼的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Go語(yǔ)言實(shí)現(xiàn)順序存儲(chǔ)的線性表實(shí)例

    Go語(yǔ)言實(shí)現(xiàn)順序存儲(chǔ)的線性表實(shí)例

    這篇文章主要介紹了Go語(yǔ)言實(shí)現(xiàn)順序存儲(chǔ)的線性表的方法,實(shí)例分析了Go語(yǔ)言實(shí)現(xiàn)線性表的定義、插入、刪除元素等的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • 為什么Go里值為nil可以調(diào)用函數(shù)原理分析

    為什么Go里值為nil可以調(diào)用函數(shù)原理分析

    這篇文章主要為大家介紹了為什么Go里值為nil可以調(diào)用函數(shù)原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • golang1.21新特性全面講解

    golang1.21新特性全面講解

    經(jīng)過了半年左右的開發(fā),golang?1.21?最近正式發(fā)布了,這個(gè)版本中有不少重要的新特性和變更,尤其是在泛型相關(guān)的代碼上,下面小編就來和大家好好嘮嘮吧
    2023-08-08
  • 瞅一眼就能學(xué)會(huì)的GO并發(fā)編程使用教程

    瞅一眼就能學(xué)會(huì)的GO并發(fā)編程使用教程

    隨著互聯(lián)網(wǎng)的普及,互聯(lián)網(wǎng)用戶人數(shù)原來越多,這對(duì)系統(tǒng)的性能帶來了巨大的挑戰(zhàn)。這個(gè)時(shí)候就需要并發(fā)編程了,本文為大家整理了詳細(xì)的GO并發(fā)編程使用教程,讓你看完就能學(xué)會(huì)
    2023-02-02
  • Go實(shí)現(xiàn)短url項(xiàng)目的方法示例

    Go實(shí)現(xiàn)短url項(xiàng)目的方法示例

    這篇文章主要介紹了Go實(shí)現(xiàn)短url項(xiàng)目的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • 使用go語(yǔ)言實(shí)現(xiàn)cors中間件

    使用go語(yǔ)言實(shí)現(xiàn)cors中間件

    CORS是一種瀏覽器安全機(jī)制,用于控制在Web應(yīng)用程序中不同源(Origin)之間的資源共享,本文將給大家介紹如何使用go語(yǔ)言實(shí)現(xiàn)cors中間件,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2023-09-09
  • Go使用pprof進(jìn)行CPU,內(nèi)存和阻塞情況分析

    Go使用pprof進(jìn)行CPU,內(nèi)存和阻塞情況分析

    Go 語(yǔ)言提供了強(qiáng)大的 pprof工具,用于分析 CPU、內(nèi)存、Goroutine 阻塞等性能問題,幫助開發(fā)者優(yōu)化程序,提高運(yùn)行效率,下面我們就來深入了解下pprof 的使用吧
    2025-03-03
  • 為什么不建議在go項(xiàng)目中使用init()

    為什么不建議在go項(xiàng)目中使用init()

    這篇文章主要介紹了為什么不建議在go項(xiàng)目中使用init(),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04

最新評(píng)論