Rust主线程定义的变量在子线程的正确用法及E0597错误如何解决?
错误原因
你的理解基本正确,核心是Rust的线程生命周期约束和字符串借用规则冲突:
clap::App::get_matches返回的matches变量是所有命令行参数的所有者,matches.value_of("latency")返回的是借自matches的&str类型,生命周期和matches绑定。std::thread::spawn创建的子线程闭包要求满足'static生命周期约束:Rust无法保证子线程的执行时长一定短于主线程的matches变量存活时长,因此禁止子线程持有主线程变量的借用。- 你之前克隆
latency_pairs没用的原因是,你克隆的是存储&str的向量,向量里的字符串切片仍然是借自matches的引用,没有解除和matches的生命周期绑定。
修复方法
只需要把需要传到子线程的字符串从借用的&str转为持有所有权的String类型,彻底解除对matches的依赖即可,修改后的代码如下:
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"); // 在这里转为String,拿到所有权,不再借用matches let latency = matches.value_of("latency").unwrap_or("1000:10,300:30").to_string(); // split后每个元素都转为String,存储到Vec里,所有数据都是owned类型 let latency_pairs: Vec<String> = latency.split(",").map(|s| s.to_string()).collect(); let checker = std::thread::spawn(move || -> GenericResult<()>{ loop { if latency_present { for (i, latency_pair) in latency_pairs.iter().enumerate() { // 后续使用latency_pair的时候不用改,&String可以自动解引用为&str // let latency_pair: Vec<&str> = latency_pair.split(":").collect(); // let latency = latency_pair[0].parse::<f64>().unwrap(); } } } }); checker.join().unwrap()?; Ok(()) }
内容的提问来源于stack exchange,提问作者user130268
相关产品推荐
相关产品推荐

