在 Rust 的子线程中使用在主线程中定义的变量的正确方法是什么?

What's the proper way to use variables defined in the main thread in a child thread in Rust?

我是 Rust 新手,仍在阅读 Rust 书籍。下面是我的程序。

use clap::{App, Arg};

type GenericError = Box<dyn std::error::Error + Send + Sync + 'static>;
type GenericResult<T> = Result<T, GenericError>;

fn main() -> GenericResult<()> {
    let matches = App::new("test")
        .arg(Arg::new("latency")
            .takes_value(true))
        .get_matches();


    let latency_present = matches.is_present("latency");
    let latency = matches.value_of("latency").unwrap_or("1000:10,300:30");
    let latency_pairs: Vec<&str> = latency.split(",").collect();

    let checker = std::thread::spawn(move || -> GenericResult<()>{
        loop {
            if latency_present {
                for (i, latency_pair) in latency_pairs.iter().enumerate() {
                    // let latency_pair: Vec<&str> = latency_pair.split(":").collect();
                    // let latency = latency_pair[0].parse::<f64>().unwrap();
                }
            }
        }
    });

    checker.join().unwrap()?;
    Ok(())
}

当我 运行 它时,它告诉我:

error[E0597]: `matches` does not live long enough
  --> src\main.rs:14:19
   |
14 |     let latency = matches.value_of("latency").unwrap_or("1000:10,300:30");
   |                   ^^^^^^^--------------------
   |                   |
   |                   borrowed value does not live long enough
   |                   argument requires that `matches` is borrowed for `'static`
...
30 | }
   | - `matches` dropped here while still borrowed

我不太明白这里的错误信息。但我想这是因为我在 checker 线程中使用了 latency_pairs 并且 latency_pairs 可能会在 checker 仍在执行时被丢弃。我的理解正确吗?如何修复错误?我尝试 for (i, latency_pair) in latency_pairs.clone().iter().enumerate() { 以便为线程传递克隆值,但没有帮助。

latency_pairs 保存对 latency 的引用,后者又引用 matches。因此克隆 latency_pairs 只是将引用克隆到 latencymatches.

您的代码要求 latency 的类型是 &'static str,但它实际上是 &'a str,其中 'a 绑定到 matches 的生命周期。

您可以在 latency 上调用 to_owned() 以获取拥有的值并在闭包内拆分字符串,或者您可以在 [=12] 中收集的每个拆分上调用 to_owned() =] 并将 Vec<String> 移动到闭包中:

    let latency_pairs: Vec<String> = latency.split(",").map(ToOwned::to_owned).collect();

    let checker = std::thread::spawn(move || -> GenericResult<()>{
        loop {
            if latency_present {
                for (i, latency_pair) in latency_pairs.iter().enumerate() {
                    // let latency_pair: Vec<&str> = latency_pair.split(":").collect();
                    // let latency = latency_pair[0].parse::<f64>().unwrap();
                }
            }
        }
    });

如果您需要在闭包外使用 latency_pairs,您可以在将其移入闭包之前克隆它:

    let latency_pairs: Vec<String> = latency.split(",").map(ToOwned::to_owned).collect();
    let latency_pairs_ = latency_pairs.clone();
    let checker = std::thread::spawn(move || -> GenericResult<()>{
        loop {
            if latency_present {
                for (i, latency_pair) in latency_pairs_.iter().enumerate() {
                    // let latency_pair: Vec<&str> = latency_pair.split(":").collect();
                    // let latency = latency_pair[0].parse::<f64>().unwrap();
                }
            }
        }
    });
    println!("{:?}", latency_pairs);