You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何共享模块中函数返回的Struct,避免重复获取环境变量?

使用lazy_static缓存环境变量Struct,避免重复初始化

没问题,我来帮你梳理清楚怎么用lazy_static实现这个需求。核心思路就是让Config实例只初始化一次,之后所有地方都复用这个实例,不用每次都重新加载.env和解析环境变量。

第一步:完善src/env.rs的代码

首先我们把重复的初始化逻辑抽成一个私有函数,然后用lazy_static创建一个全局的静态引用,这样第一次访问时才会初始化:

use serde::Deserialize;
extern crate dotenv;
extern crate lazy_static;
use lazy_static::lazy_static;

#[derive(Deserialize, Debug)]
pub struct Config {
    pub redis: String,
    pub profile: String,
}

// 抽离初始化逻辑,避免代码冗余
fn load_config() -> Config {
    dotenv::dotenv().expect("Failed to read .env file");
    match envy::from_env::<Config>() {
        Ok(config) => config,
        Err(e) => panic!("{:#?}", e),
    }
}

// 创建全局静态引用,第一次访问时初始化,之后复用
lazy_static! {
    pub static ref ENV: Config = load_config();
}

// 可选:如果你想保留原来的get()接口,可以改成返回引用
pub fn get() -> &'static Config {
    &ENV
}

别忘了在Cargo.toml里添加lazy_static依赖:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
dotenv = "0.15"
envy = "0.4"
lazy_static = "1.4"

第二步:在main.rs中访问缓存的环境变量

现在你有两种方式可以获取Config实例,选你习惯的就行:

mod env;

async fn main() {
    // 方式1:直接访问全局静态引用ENV
    println!("Profile: {}", env::ENV.profile);
    println!("Redis address: {}", env::ENV.redis);

    // 方式2:如果保留了get()函数,用原来的调用方式也可以
    let config = env::get();
    println!("Profile (via get()): {}", config.profile);
    println!("Redis address (via get()): {}", config.redis);
}

为什么这样做?

  • lazy_static的static ref会保证初始化只执行一次,不管你访问多少次env::ENV或者调用多少次env::get(),都不会重复读取.env文件或解析环境变量,提升了性能。
  • 因为你的Config所有字段都是String,自动实现了Sync和Send trait,所以这个全局实例在多线程环境下使用也是安全的。

内容的提问来源于stack exchange,提问作者ZiiMakc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:03:13