在 Rust 中运行时使用环境变量填充 static/const

问题描述 投票:0回答:2

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

const PASSWORD: String = var("PASSWORD").unwrap();

不起作用,因为

method calls in constants are limited to constant  inherent methods
。这同样适用于
static
(显然,错误表示静态)。

我见过的另一种方法是

const PASSWORD: &'static str = env!("PASSWORD");

但问题是它将在编译时定义为

env!
是一个宏(至少这是我的理解)。

我还考虑过简单地将对

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

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

,我真的很感激
static environment-variables rust constants
2个回答
20
投票

const
static
在 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); }

首次访问变量时,执行表达式以加载其值,然后该值被记忆并可用,直到程序结束。


0
投票
Matthieu M.所说的

仍然是正确的,尽管现在你应该使用OnceLock

而不是
lazy_static
use std::sync::OnceLock;
use std::env::var;
fn password() -> &'static str {
    static PASSWORD: OnceLock<String> = OnceLock::new();
    PASSWORD.get_or_init(|| {
        var("PASSWORD").unwrap()
    })
}

一旦稳定或每晚您可以简化为
LazyLock

#![feature(lazy_cell)]
use std::sync::LazyLock;
use std::env::var;
static PASSWORD: LazyLock<String> = LazyLock::new(|| {
    var("PASSWORD").unwrap()
});

© www.soinside.com 2019 - 2024. All rights reserved.