如何在不复制的情况下将"str"借给一个线程?

Mag*_*off 1 lifetime rust

特定

fn greet(peeps: &str) {
    println!("Hello, {}", peeps);
}
Run Code Online (Sandbox Code Playgroud)

我可以:

fn main() {
    let a = "World";
    thread::spawn(move || greet(a)).join().unwrap();
}
Run Code Online (Sandbox Code Playgroud)

编译器理解线程不会比借用的字符串更长,但这只是&str已知生命周期的特殊情况'static.当我尝试使用函数参数执行相同操作时,它不会编译:

fn indirect(peeps: &str) {
    thread::spawn(move || greet(&peeps)).join().unwrap();
    // Does not compile, for fear that the thread may outlive peeps
}
Run Code Online (Sandbox Code Playgroud)

然而,对于人类读者来说,显然情况是线程不能比借来的字符串寿命更长.

我找到了两个解决方法:

  1. 复制字符串,可以将其移动到线程中:

    fn indirect(peeps: &str) {
        let peeps = peeps.to_string();
        thread::spawn(move || greet(&peeps)).join().unwrap();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 或者,利用着名的弃用thread::scoped:

    #![feature(scoped)]
    fn indirect_scoped(peeps: &str) {
        thread::scoped(move || greet(&peeps)).join();
    }
    
    Run Code Online (Sandbox Code Playgroud)

我不想'static为函数参数指定生命周期,我不想做出不必要的复制(解决方法1),我不想使用不推荐使用的功能(解决方法2).

在这种情况下我该怎么办?

Vla*_*eev 6

scoped()当您想将借用的数据传递给子线程时,方法是正确的方法.虽然thread::scoped()本身是由于弃用它的不健全,另一种声音API,如横梁scoped_threadpool提供一种方式来做到这一点的稳定的锈:

extern crate crossbeam;

fn indirect(peeps: &str) {
    crossbeam::scope(|scope| {
        scope.spawn(|| greet(peeps));
    });
}
Run Code Online (Sandbox Code Playgroud)