分配给静态变量时出现 Rust 'borrowed value does not live long enough'

标签 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() {
      "/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.")
        }
      }
    }
  }
}

出现以下编译错误

error[E0597]: `args` does not live long enough
   --> src\main.rs:90:34
    |
90  |                 ROOT_DIRECTORY = args.get(index + 1).unwrap();
    |                                  ^^^^---------------
    |                                  |
    |                                  borrowed value does not live long enough
    |                                  argument requires that `args` is borrowed for `'static`
...
168 | }
    | - `args` dropped here while still borrowed

error[E0382]: borrow of moved value: `args`
  --> src\main.rs:90:34
   |
54 |     let args: Vec<String> = env::args().collect();
   |         ---- move occurs because `args` has type `std::vec::Vec<std::string::String>`, which does not implement the `Copy` trait
...
76 |     for arg in args {
   |                ----
   |                |
   |                value moved here
   |                help: consider borrowing to avoid moving into the for loop: `&args`
...
90 |                 ROOT_DIRECTORY = args.get(index + 1).unwrap();
   | 

有什么方法可以让我从迭代器创建值的静态副本吗?

最佳答案

你不能那样做。静态变量必须是 'static ,即不得包含非 'static一生。这就是为什么您可以在静态引用声明中省略生命周期。你的实际上相当于:

static mut ROOT_DIRECTORY: &'static str = "C:\\test\\source";

还有你的args是一个局部变量,所以对它的引用不是 'static .

Is there any way for me to create a static copy of the value from the iterator?

最简单的选择是让静态变量拥有自己的数据,而不是作为引用,也就是说,让它成为 String 。不幸的是,静态构造函数必须是 const ,以及唯一的const String 的构造函数我所知道的是String::new() 。您可以添加一个辅助函数 fn get_root_directory() -> &'static str读取全局变量并在未设置时返回默认值,但如果您对此感兴趣,则可以将静态设置为 Option<String> :

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());
    }
}

关于分配给静态变量时出现 Rust 'borrowed value does not live long enough',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60580754/

相关文章:

rust - web_sys crate 是如何工作的?

c++ - C++ 类的静态数据成员的多态性

Java:静态初始化

compiler-errors - Rust 借用编译错误

rust - 迭代特征对象的可变引用向量

generics - 有没有办法在 Rust 中模拟通用关联类型/关联类型构造函数?

rust - 我如何编写一个方法来包装我的类型中的任何值,可以多次调用而不需要类型注释?

datetime - 如何将 chrono::Datetime 舍入到最接近的秒数?

java - 错误 : non-static variable this cannot be referenced from a static context

rust - 为什么我不能阻止一个盒子?