如何在线程中使用静态生命周期?

mar*_*tur 8 channel rust lifetime-scoping

我目前正在Rust(1.0)的生命中挣扎,特别是在通过通道传递结构时.

我将如何编译这个简单的例子:

use std::sync::mpsc::{Receiver, Sender};
use std::sync::mpsc;
use std::thread::spawn;
use std::io;
use std::io::prelude::*;

struct Message<'a> {
    text: &'a str,
}

fn main() {
    let (tx, rx): (Sender<Message>, Receiver<Message>) = mpsc::channel();

    let _handle_receive = spawn(move || {
        for message in rx.iter() {
            println!("{}", message.text);
        }
    });

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let message = Message {
            text: &line.unwrap()[..],
        };
        tx.send(message).unwrap();
    }
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:23:20
   |
23 |             text: &line.unwrap()[..],
   |                    ^^^^^^^^^^^^^ does not live long enough
...
26 |     }
   |     - temporary value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...
Run Code Online (Sandbox Code Playgroud)

我可以看出为什么这是(line只适用于一次迭代for),但我无法弄清楚这样做的正确方法是什么.

  • 我应该像编译器提示的那样尝试将其转换&str&'static str
  • 如果每一条线路都有'static生命周期,我会泄漏记忆吗?
  • 我应该'static什么时候使用?这是我应该避免的还是完全没问题?
  • 是否有更好的方法String通过通道传递结构?

我为那些天真的问题道歉.我已经花了很长时间搜索,但我不能完全围绕它.这可能是我的动态语言背景阻碍了:)

暂且不说:&input[..]将a转换String成一个&str考虑好的?这是我能找到的唯一稳定的方法.

小智 12

除了泄漏内存外,你无法转换&'a T&'static T.幸运的是,这根本不是必需的.没有理由将借用的指针发送到线程并将线保留在主线程上.您不需要主线程上的行.只需发送线路,即发送String.

如果需要从多个线程进行访问(并且您不想克隆),请使用Arc<String>(将来Arc<str>也可以使用).这样,字符串在线程之间共享,正确共享,因此当没有线程再次使用它时,它将被准确释放.

'static在线程之间发送非引用是不安全的,因为您永远不知道其他线程将继续使用多长时间,因此您不知道借用何时到期并且可以释放该对象.请注意,作用域线程没有这个问题(不是在1.0中,而是在我们说的时候重新设计)允许这样做,但是常规的spawned线程会这样做.

'static不是你应该避免的东西,它完全可以做它的作用:表示一个值在程序运行的整个持续时间内存在.但如果这不是你想传达的东西,当然这是错误的工具.