Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use static lifetimes with threads?

Tags:

I'm currently struggling with lifetimes in Rust (1.0), especially when it comes to passing structs via channels.

How would I get this simple example to compile:

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();
    }
}

I get:

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...

I can see why this is (line only lives for one iteration of for), but I can't figure out what the right way of doing this is.

  • Should I, as the compiler hints, try to convert the &str into &'static str?
  • Am I leaking memory if every line would have a 'static lifetime?
  • When am I supposed to use 'static anyway? Is it something I should try to avoid or is it perfectly OK?
  • Is there a better way of passing Strings in structs via channels?

I apologize for those naive questions. I've spent quite some time searching already, but I can't quite wrap my head around it. It's probably my dynamic language background getting in the way :)

As an aside: Is &input[..] for converting a String into a &str considered OK? It's the only stable way I could find to do this.