在Rust的运行时使用环境变量填充静态/常量

dav*_*ave 5 static const environment-variables rust

我正在尝试在服务启动时从系统环境中加载密码和敏感数据。我尝试了许多不同的方法,但似乎无法找出在Rust中执行此操作的正确方法。

const PASSWORD: String = var("PASSWORD").unwrap();
Run Code Online (Sandbox Code Playgroud)

不起作用,因为method calls in constants are limited to constant inherent methods。这同样适用static(显然错误是静态的)。

我见过的另一种方法是

const PASSWORD: &'static str = env!("PASSWORD");
Run Code Online (Sandbox Code Playgroud)

但是这样做的问题是,它将像env!宏一样在编译时进行定义(至少这是我的理解)。

我还考虑过将调用包装到var("...").unwrap()一个函数中,但是该解决方案并不适合我,而且还允许在整个运行时更改值,并且在服务启动时不验证它们。

如您所知,我是Rust的新手。如果您在回答中不能仅解释如何在运行时加载const / static,还可以解释为什么我在做的是愚蠢的和错误的,我将不胜感激:)

Mat*_* M. 5

conststatic在Rust中扮演不同的角色。

const不仅表示常量,还表示编译时常量,它是在编译时确定并写入程序只读存储器的值。它不适合您的用例。

static表示一个全局变量,其生存期将覆盖整个程序。它可能是可变的,在这种情况下,必须Sync避免并行修改。甲static变量必须从恒定被初始化,以便可以从该程序的开始。

那么,如何在运行时读取变量并使变量可用?好吧,一个干净的解决方案是完全避免全球化。

...但因为它很方便,所以有一个包装箱:lazy_static!

use std::env::var;
use lazy_static::lazy_static;

lazy_static! {
    static ref PASSWORD: String = var("PASSWORD").unwrap();
}

fn main() {
    println!("{:?}", *PASSWORD);
}
Run Code Online (Sandbox Code Playgroud)

首次访问该变量时,将执行该表达式以加载其值,然后将该值存储起来并可用,直到程序结束。

  • @dave:这就是在Rust中处理全局变量的方法,只要在第一个机会(主要是)就访问它们,它们就会在最早的时间加载。至于不使用全局变量,为什么不简单地在变量中检索密码,然后将其(通过参数)传递给需要的人呢?具有相同的功能,但可以明确指出哪个代码块可以访问密码。 (3认同)
  • @Rokit:确实如此。我还更新了代码片段以提供 [MVCE],如果我们在问题中要求它,没有理由不在答案中提供它:) (2认同)