【发布时间】:2023-02-17 17:20:34
【问题描述】:
如果设置了某些环境变量,我想更改参数列表。参数列表是一个元组向量,每个元组有两个字符串切片。
应该这样做的代码:
use std::env;
fn main() {
let mut params = vec![
// there is a whole list of default params
("param", "value"),
];
if let Ok(extra_param) = env::var("EXTRA_PARAM") {
params.push(("extra_param", &extra_param));
};
dbg!(params);
}
当然,它不起作用,因为 extra_params 属于本地 if let 范围,编译器会产生以下错误:
$ EXTRA_PARAM=extra_value cargo run
error[E0597]: `extra_param` does not live long enough
--> src/main.rs:10:37
|
10 | params.push(("extra_param", &extra_param));
| ^^^^^^^^^^^^ borrowed value does not live long enough
11 | };
| - `extra_param` dropped here while still borrowed
12 |
13 | dbg!(params);
| ------ borrow later used here
For more information about this error, try `rustc --explain E0597`.
error: could not compile `question` due to previous error
我通过在外部作用域中添加一个变量并在引用它之前复制内部变量的值来解决这个问题:
let external_param;
if let Ok(extra_param) = env::var("EXTRA_PARAM") {
external_param = extra_param;
params.push(("extra_param", &external_param));
};
现在,我的程序按预期工作,但解决方案感觉平庸。
我错过了什么?有没有什么办法可以得到Result,这样代码就不会那么笨拙了?
我想在不改变元组内部类型的情况下解决这个问题,所以它们仍然是字符串切片,因为它们中有很多是在代码中定义的,我只需要一个额外的参数来有条件地添加。
【问题讨论】:
-
是什么明确的
params的类型?是Vec<(&'static str, &'static str)>还是Vec<(&'static str, String)>?或者是其他东西?我认为这会指出你想做什么,而不是你正在做什么。std::env::var返回Result<String, VarError>,所以我想知道你的Vec最终包含什么。 -
它是通过分配
vec![("param", "value")]'来定义的,所以它只是Vec<(&str, &str)>。或者至少它是来自 VSCode 的rust-analyzer在屏幕上打印的内容。 -
不要从我所说的中删除生命周期。如果您使用
&str而不是String,请务必了解您正在使用的生命周期。如果它是切片,您的向量将一无所有。如果有些是staticlifetime,那很重要。 -
当您在外部有很多参考而内部参考很少时,这是针对这种情况的完美解决方案。
-
这是一个很好的解决方案,因为它确实正确地指示了您希望底层
str存活多长时间。您也可以将String泄漏到&'static str中,但这意味着它将永远存在,而不是在变量external_param的范围内生存,后者更容易控制。
标签: rust