在实际开发中,我们常常需要根据不同环境(开发、测试、生产)来配置数据库地址、端口号、API 密钥等信息。环境变量(Environment Variables)是最常见、最安全的一种配置方式。
本文将从两个方面介绍如何在 Go 项目中使用环境变量:
- 使用标准库(不依赖任何第三方库)
- 使用
viper
1、使用 Go 标准库读取环境变量(推荐方式)
Go 提供了 os
包来处理环境变量,无需引入任何第三方依赖,非常适合对依赖敏感的项目。
1.1 os.Getenv()
读取变量
package main
import (
"fmt"
"os"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080" // 设置默认值
}
fmt.Println("PORT:", port)
}
1.2 os.LookupEnv()
更安全的读取方式
if value, exists := os.LookupEnv("DB_HOST"); exists {
fmt.Println("DB_HOST:", value)
} else {
fmt.Println("DB_HOST is not set")
}
1.3 os.Setenv()
设置环境变量(仅对当前进程有效)
os.Setenv("PORT", "3000")
注意:这个设置只在当前 Go 程序运行期间有效,不会影响系统或其他进程。
2、手动解析 .env
文件(无第三方库)
虽然 Go 没有内建对 .env
文件的支持,我们可以手动读取 .env
文件并使用 os.Setenv()
进行配置:
示例代码:
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func loadEnvFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "#") || strings.TrimSpace(line) == "" {
continue
}
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
os.Setenv(key, value)
}
return scanner.Err()
}
func main() {
err := loadEnvFile(".env")
if err != nil {
fmt.Println("Failed to load .env:", err)
}
fmt.Println("DB_HOST:", os.Getenv("DB_HOST"))
}
示例 .env
文件:
DB_HOST=localhost
DB_USER=root
3、使用 viper
读取环境变量(支持系统和 .env
)
viper
是 Go 中功能最强大的配置库之一。它支持多种格式(JSON、TOML、YAML、env)以及多种配置源(文件、环境变量、远程配置等)。
3.1 从系统环境变量读取
import (
"fmt"
"github.com/spf13/viper"
)
func main() {
viper.SetDefault("PORT", "8080")
viper.BindEnv("PORT")
fmt.Println("PORT:", viper.GetString("PORT"))
}
如果你在 bash 中设置了 export PORT=3000
,程序将读取到它。
3.2 自动绑定所有环境变量
viper.AutomaticEnv()
这样可以自动获取所有环境变量,无需显式调用 BindEnv
。
3.3 配合 .env
文件(需 godotenv
库)
虽然 viper
不直接支持 .env
文件,但可以配合 github.com/joho/godotenv
使用:
import (
"fmt"
"github.com/joho/godotenv"
"github.com/spf13/viper"
"log"
)
func main() {
err := godotenv.Load(".env")
if err != nil {
log.Fatal("Error loading .env file")
}
viper.BindEnv("DB_HOST")
viper.BindEnv("DB_USER")
fmt.Println("DB_HOST:", viper.GetString("DB_HOST"))
fmt.Println("DB_USER:", viper.GetString("DB_USER"))
}
4、总结对比
场景 | 推荐方法 | 是否依赖第三方 |
---|---|---|
系统环境变量读取 | os.Getenv() / viper.BindEnv |
否 / 是 |
加载 .env 文件 |
手动解析 / godotenv + viper |
否 / 是 |
自动绑定所有变量 | viper.AutomaticEnv() |
是 |
复杂配置文件(YAML等) | viper |
是 |

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
腾讯云开发者社区:孟斯特
—