延长线程变量的生命周期
Extend lifetime of a variable for thread
我正在从文件中读取一个字符串,将其按行拆分为一个向量,然后我想在单独的线程中对提取的行执行某些操作。像这样:
use std::fs::File;
use std::io::prelude::*;
use std::thread;
fn main() {
match File::open("data") {
Ok(mut result) => {
let mut s = String::new();
result.read_to_string(&mut s);
let k : Vec<_> = s.split("\n").collect();
for line in k {
thread::spawn(move || {
println!("nL: {:?}", line);
});
}
}
Err(err) => {
println!("Error {:?}",err);
}
}
}
当然这会引发错误,因为 s
将在线程启动之前超出范围:
s` does not live long enough
main.rs:9 let k : Vec<_> = s.split("\n").collect();
^
我现在可以做什么?我试过很多东西,比如 Box
或 Arc
,但我无法让它工作。我不知何故需要创建一个 s
的副本,它也存在于线程中。但是我该怎么做呢?
从根本上说,问题在于 line
是 s
的借用切片。在这里你真的无能为力,因为没有办法保证每个 line
不会超过 s
本身。
此外,需要明确的是:在 Rust 中 绝对没有办法 到 "extend the lifetime of a variable"。根本做不到。
解决此问题的最简单方法是从 line
被 借用 变为 拥有 。像这样:
use std::thread;
fn main() {
let mut s: String = "One\nTwo\nThree\n".into();
let k : Vec<String> = s.split("\n").map(|s| s.into()).collect();
for line in k {
thread::spawn(move || {
println!("nL: {:?}", line);
});
}
}
.map(|s| s.into())
从 &str
转换为 String
。由于 String
拥有它的内容,它可以安全地移动到每个线程的闭包中,并且独立于创建它的线程。
注意:您可以使用新作用域线程API在夜间 Rust 中执行此操作,但这仍然不稳定.
我正在从文件中读取一个字符串,将其按行拆分为一个向量,然后我想在单独的线程中对提取的行执行某些操作。像这样:
use std::fs::File;
use std::io::prelude::*;
use std::thread;
fn main() {
match File::open("data") {
Ok(mut result) => {
let mut s = String::new();
result.read_to_string(&mut s);
let k : Vec<_> = s.split("\n").collect();
for line in k {
thread::spawn(move || {
println!("nL: {:?}", line);
});
}
}
Err(err) => {
println!("Error {:?}",err);
}
}
}
当然这会引发错误,因为 s
将在线程启动之前超出范围:
s` does not live long enough
main.rs:9 let k : Vec<_> = s.split("\n").collect();
^
我现在可以做什么?我试过很多东西,比如 Box
或 Arc
,但我无法让它工作。我不知何故需要创建一个 s
的副本,它也存在于线程中。但是我该怎么做呢?
从根本上说,问题在于 line
是 s
的借用切片。在这里你真的无能为力,因为没有办法保证每个 line
不会超过 s
本身。
此外,需要明确的是:在 Rust 中 绝对没有办法 到 "extend the lifetime of a variable"。根本做不到。
解决此问题的最简单方法是从 line
被 借用 变为 拥有 。像这样:
use std::thread;
fn main() {
let mut s: String = "One\nTwo\nThree\n".into();
let k : Vec<String> = s.split("\n").map(|s| s.into()).collect();
for line in k {
thread::spawn(move || {
println!("nL: {:?}", line);
});
}
}
.map(|s| s.into())
从 &str
转换为 String
。由于 String
拥有它的内容,它可以安全地移动到每个线程的闭包中,并且独立于创建它的线程。
注意:您可以使用新作用域线程API在夜间 Rust 中执行此操作,但这仍然不稳定.