我正在尝试在服务启动时从系统环境中加载密码和敏感数据。我已经尝试了许多不同的方法,但似乎找不到在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()
的调用 Package 在一个函数中,但该解决方案并不适合我,并且还允许在整个运行时更改值,并且在服务启动时不验证它们。
正如你所看到的,我对Rust是个新手。我真的很感激你的回答,如果你不能只是解释如何在运行时加载const/static,但也解释为什么我做的是愚蠢和错误的:)
2条答案
按热度按时间7eumitmz1#
const
和static
在Rust中扮演不同的角色。const
不仅意味着一个常数,它还意味着一个 * 编译时 * 常数,一个在编译时确定的值,并记录在程序的只读存储器中。它不适合你的情况。static
表示一个全局变量,其生存期将跨越整个程序。它可能是可变的,在这种情况下,它必须是Sync
以避免并发修改。static
变量必须从常量初始化,以便在程序开始时可用。那么,如何在运行时读取变量并使其可用呢?好吧,一个干净的解决方案是完全避免全局变量...
.但由于它可以方便,有一个板条箱:
lazy_static!
。在第一次访问变量时,执行表达式以加载其值,然后将值存储并可使用,直到程序结束。
ukdjmx9f2#
所有Matthieu M. said仍然是正确的,尽管现在你应该使用
OnceLock
而不是lazy_static
:一旦它稳定或每晚运行,您可以简化为
LazyLock
:您还可以通过使用
Box<str>
而不是String
并对字符串调用.into()
来为每个变量保存一个字(根据String
实际上是如何分配的,可能会保存更多字),但这可能涉及到对字符串内容的额外复制。