Rust 应用配置:config 和 dotenv 库

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust 应用配置:config 和 dotenv 库



任何现代应用都需要灵活的配置系统:数据库设置、API 密钥、服务器端口、日志级别和其他参数。在 Rust 生态系统中,有强大的工具——config 和 dotenv crate。它们允许将来自不同来源(文件、环境变量、命令行参数)的设置合并到一个类型安全的结构中。



为什么需要单独的库?

Rust 是一种强静态类型语言。简单地从 std::env::var() 读取字符串会导致大量手动检查和转换。config 库自动化了这一过程:

  • 支持格式:YAML、JSON、TOML、HJSON、INI、RON
  • 支持覆盖的层次化设置结构
  • 通过 serde 自动反序列化为用户自定义结构
  • 合并多个具有优先级的来源(文件 < env < CLI)


安装

在 Cargo.toml 中添加:

[dependencies]config = "0.14"serde = { version = "1.0", features = ["derive"] }dotenv = "0.15"


基本示例:从文件和 env 读取

创建一个应用配置结构:

use serde::Deserialize;use config::Config;

#[derive(Debug, Deserialize)]struct AppConfig { server: ServerConfig, database: DatabaseConfig,}

#[derive(Debug, Deserialize)]struct ServerConfig { host: String, port: u16, workers: u8,}

#[derive(Debug, Deserialize)]struct DatabaseConfig { url: String, pool_size: u32,}

fn main() -> Result<(), config::ConfigError> { // 加载配置 let config = Config::builder() .add_source(config::File::with_name("config/default")) .add_source(config::Environment::with_prefix("APP")) .build()?;

let app_config: AppConfig = config.try_deserialize()?; println!("{:#?}", app_config); Ok(())}


config/default.toml 文件:

[server]host = "127.0.0.1"port = 8080workers = 4

[database]url = "postgres://localhost/mydb"pool_size = 10


带有前缀 APP_ 的环境变量会覆盖文件中的值。例如,APP_DATABASE__URL 将更改数据库 URL。



使用 dotenv

为了方便开发,通常使用 .env 文件。dotenv crate 在初始化 config 之前将其加载到环境变量中:

use dotenv::dotenv;

fn main() { dotenv().ok(); // 加载 .env // 然后像上面的示例一样初始化 config}


.env 文件内容:

APP_SERVER__PORT=3000APP_DATABASE__POOL_SIZE=20


高级场景:多个来源

实际项目需要组合来自不同位置的设置。config 允许设置具有优先级的来源链:

let config = Config::builder()    // 基本设置(低优先级)    .add_source(config::File::with_name("config/default"))    // 特定环境的覆盖    .add_source(config::File::with_name(&format!("config/{}", env::var("APP_ENV").unwrap_or("development"))))    // 环境变量(中等优先级)    .add_source(config::Environment::with_prefix("APP"))    // 命令行参数(高优先级)    .add_source(config::File::from(std::env::args().nth(1).unwrap_or_default()))    .build()?;


最佳实践

  • 为环境变量使用前缀,以避免与系统变量冲突

推荐