2016-04-09 13 views
5

Sto creando un'applicazione multi-thread in cui creo un canale di ricezione e una struttura per contenere il canale di invio (da utilizzare successivamente dall'implementazione). Tuttavia, il tipo che sto inviando attraverso il canale ha una specifica a vita. Questo tipo è websocket::message:Message dalla libreria rusts-weboscket. A causa di questa specifica, la ruggine non sembra in grado di inferire correttamente le vite una volta passata attraverso un filo.Rust Lifetimes con mpsc :: Sender <T<'a>> e threads

Ecco un esempio di parco giochi di ruggine di questo errore: https://play.rust-lang.org/?gist=7e37547d1c811185654f10a6a461e1ef&version=stable&backtrace=1

Ora, ho provato ad utilizzare traversa a scopo il corso della vita, e questo sembra risolvere il problema immediato, ma in pratica solo i delegati alla questione specifica di vita da qualche parte altro.

Nel mio codice ottengo l'errore:

$ cargo check 
    Compiling rump v0.1.0 (file:///home/alainh/UPenn/CIS198/Rump) 
transport.rs:200:42: 200:57 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements [E0495] 
transport.rs:200   self.sender.send(self.serializer.encode(message)); 
                  ^~~~~~~~~~~~~~~ 
transport.rs:199:5: 202:6 help: consider using an explicit lifetime parameter as shown: fn send<T: Encodable>(&'a mut self, message: &T) -> WampResult<()> 
transport.rs:199  fn send<T: Encodable>(&mut self, message: &T) -> WampResult<()> { 
transport.rs:200   self.sender.send(self.serializer.encode(message)); 
transport.rs:201   Ok(()) 
transport.rs:202  } 
error: aborting due to previous error 
Could not compile `rump`. 

La linea in questione è questo: https://github.com/aehernandez/Rump/blob/ad717c7ef11857e94d0e1c02539667c8034676c4/src/transport.rs#L199

A questo punto io sono sicuro esattamente come risolvere questo problema tutta la vita. Non voglio continuare a delegarlo da qualche altra parte. C'è una buona soluzione a questo?

risposta

3

Quando si genera un thread può potenzialmente vivere per sempre; sicuramente sopravviverà il tuo tipo Transport<'a> per tutta la vita 'a diverso da 'static (i messaggi di errore sono però molto confusi). Quando si chiama thread::spawn con una chiusura, tale chiusura deve avere la durata 'static, che è vera solo se 'a == 'static.

Come non si è in realtà l'invio di un oggetto con un corso della vita attraverso il canale, è possibile utilizzare la durata 'static esplicitamente:

impl Connector for Transport<'static> { 
    ... 
} 

Playpen

Edit:

annotare manualmente i tipi per il mittente e destinatario

let (tx, rx): (mpsc::Sender<Message<'a>>, mpsc::Receiver<Message<'a>>) = mpsc::channel(); 
    let tx_send: mpsc::Sender<Message<'a>> = tx.clone(); 

si mostra un errore molto più sensato

<anon>:27:22: 27:35 error: the type `[[email protected]<anon>:27:36: 29:10 tx_send:std::sync::mpsc::Sender<Message<'a>>]` does not fulfill the required lifetime [E0477] 
<anon>:27   let handle = thread::spawn(move || { 
           ^~~~~~~~~~~~~ 
note: type must outlive the static lifetime 
error: aborting due to previous error 
playpen: application terminated with error code 101 

Playpen