Rust 锈蚀';借来的价值活得不够长';赋值给静态变量时
我的目标是保留一个静态变量,并使该值被CLI参数覆盖,但我很难找到一种方法来保留从args迭代器获得的值的静态副本Rust 锈蚀';借来的价值活得不够长';赋值给静态变量时,rust,static,borrow-checker,borrowing,Rust,Static,Borrow Checker,Borrowing,我的目标是保留一个静态变量,并使该值被CLI参数覆盖,但我很难找到一种方法来保留从args迭代器获得的值的静态副本 static mut ROOT_DIRECTORY: &str = "C:\\test\\source"; fn main() { let args: Vec<String> = env::args().collect(); let mut index = 0; for arg in args { match arg.as_str() {
static mut ROOT_DIRECTORY: &str = "C:\\test\\source";
fn main() {
let args: Vec<String> = env::args().collect();
let mut index = 0;
for arg in args {
match arg.as_str() {
"/r" => unsafe {
if args_length <= index + 1 {
panic!("Missing root directory value.");
}
ROOT_DIRECTORY = args.get(index + 1).unwrap();
if ROOT_DIRECTORY.is_empty() {
panic!("Root directory value cannot be empty.")
}
}
}
}
}
静态mut根目录:&str=“C:\\test\\source”;
fn main(){
让args:Vec=env::args().collect();
设mut指数=0;
用于arg中的arg{
匹配参数as_str(){
“/r”=>不安全{
如果参数长度src\main.rs:90:34
|
90 | ROOT_DIRECTORY=args.get(index+1).unwrap();
| ^^^^---------------
| |
|借来的价值活得不够长
|参数要求为“静态”借用“args”`
...
168 | }
|-‘args’在这里还借着
错误[E0382]:移动值的借用:`args`
-->src\main.rs:90:34
|
54 |让args:Vec=env::args().collect();
|----发生移动是因为'args'的类型为'std::vec::vec',而该类型未实现'Copy'特性
...
76 |对于arg中的arg{
| ----
| |
|价值转移到这里
帮助:考虑借入以避免进入for循环:'& ARG'
...
90 | ROOT_DIRECTORY=args.get(index+1).unwrap();
|
有什么方法可以从迭代器创建值的静态副本吗?您不能这样做。静态变量必须是静态的,也就是说,不能包含非静态的生命期。这就是为什么您可以在静态引用声明中省略生命期。您的生命期实际上相当于:
static mut ROOT_DIRECTORY: &'static str = "C:\\test\\source";
而且您的args
是一个局部变量,因此对它的引用不是静态的
我有没有办法从迭代器创建值的静态副本
最简单的选择是让静态变量拥有自己的数据,而不是作为引用,也就是说,让它成为一个String
。不幸的是,静态构造函数必须是const
,我所知道的String
的唯一const
构造函数是String::new()
。您可以添加一个helper函数fn get_root_directory()->&'static str
,该函数读取全局变量并在未设置时返回默认值,但如果您喜欢,可以将static设置为选项
:
args列表中传递的内容不能存在于静态内存中;静态内存用于在程序执行期间存在的数据,用于作为程序二进制文件一部分的数据。您能否告诉我们您正在尝试做什么,而不是尝试编码什么?这没有意义。静态内存用于进程的生命周期当然,它可以在应用程序的执行过程中发生变异。为什么不能将一段内存提升为非空闲内存?对不起,我的观点不是静态内存不能更改,它可以在Rust中不安全地更改。但是arg或args没有静态生存期,因此不能保证在程序期间存在。不是吗谢谢,我需要使用根目录使用字符串文字。@Paul:的确,修复了。我建议使用lazy\u static!而不是不安全的代码@Polostor:lazy\u static!
的问题是OP希望使用main的参数初始化值,而不是使用静态数据。但可能一个once\u单元格将是一个很好的改进哦,我一定是忽略了这一点。嗯,once\u cell
非常适合这个。
static mut ROOT_DIRECTORY: &'static str = "C:\\test\\source";
static mut ROOT_DIRECTORY: Option<String> = None;
pub fn get_root_directory() -> &'static str {
unsafe {
ROOT_DIRECTORY.as_deref().unwrap_or("C:\\test\\source")
}
}
static mut ROOT_DIRECTORY: &'static str = "default value";
fn main() {
let x = "...".to_string();
unsafe {
ROOT_DIRECTORY = Box::leak(x.into_boxed_str());
}
}