Rust 锈蚀';借来的价值活得不够长';赋值给静态变量时

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() {

我的目标是保留一个静态变量,并使该值被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() {
      "/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());
    }
}