如何在`for_each`未来的闭包内使用`Stream`对象?

时间:2017-06-08 11:01:24

标签: rust future

我有一个接收一些websocket事件的结构。以下是从结构中接收事件的方法:

struct Connection;
impl Connection {
    pub fn recv_event(&mut self) -> Result<Event> {
        // ...
    }
}

我已经为它实施了Stream

#[cfg(feature = "stream")]
impl Stream for Connection {
    type Item = Event;
    type Error = ::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match self.recv_event() {
            Ok(event) => Ok(Async::Ready(Some(event))),
            Err(e) => Err(e),
        }
    }
}

看起来它工作正常,但后来我决定返回对Self的引用,以便能够在此代码中修改对象的状态:

connection.by_ref().for_each(|c, e| {
    println!("Event: {:?}", e);
    self.handle_events(c, e.clone());
    self.handle_messages(e);
    Ok(())
}).wait();

我需要从connection

返回对fn poll对象的引用
#[cfg(feature = "stream")]
impl Stream for Connection {
    type Item = (&mut Self, Event);
    type Error = ::Error;

    fn poll<'a>(&'a mut self) -> Poll<Option<(&'a mut Self, Event)>, Self::Error> {
        match self.recv_event() {
            Ok(event) => Ok(Async::Ready(Some(self, event))),
            Err(e) => Err(e),
        }
    }
}

不幸的是,这不起作用:

error[E0106]: missing lifetime specifier
   --> src/connection.rs:410:18
    |
410 |     type Item = (&mut Self, Event);
    |                  ^ expected lifetime parameter

是的,我忘了在这里添加一个生命周期。哎呀。我怎样才能做到这一点?我试过这个以及其他一些方法,但没有任何效果:

#[cfg(feature = "stream")]
impl<'a> Stream for Connection {
    type Item = (&'a mut Self, Event);
    type Error = ::Error;

    fn poll<'a>(&'a mut self) -> Poll<Option<(&'a mut Self, Event)>, Self::Error> {
        match self.recv_event() {
            Ok(event) => Ok(Async::Ready(Some(self, event))),
            Err(e) => Err(e),
        }
    }
}

出现错误:

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
   --> src/connection.rs:409:6
    |
409 | impl<'a> Stream for Connection {
    |      ^^ unconstrained lifetime parameter

然后我尝试了:

pub struct ConnectionStream<'a>(&'a mut Connection);
#[cfg(feature = "stream")]
impl<'a> Stream for ConnectionStream<'a> {
    type Item = (&'a mut Connection, Event);
    type Error = ::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        let res = self.0.recv_event();
        match res {
            Ok(event) => Ok(Async::Ready(Some((self.0, event)))),
            Err(e) => Err(e),
        }
    }
}

但仍然没有运气:

error[E0495]: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements
   --> src/connection.rs:417:42
    |
417 |             Ok(event) => Ok(Async::Ready(Some((self.0, event)))),
    |                                          ^^^^^^^^^^^^^^^^^^^^^
    |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 414:64...
   --> src/connection.rs:414:65
    |
414 |       fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
    |  _________________________________________________________________^ starting here...
415 | |         let res = self.0.recv_event();
416 | |         match res {
417 | |             Ok(event) => Ok(Async::Ready(Some((self.0, event)))),
418 | |             Err(e) => Err(e),
419 | |         }
420 | |     }
    | |_____^ ...ending here
note: ...so that reference does not outlive borrowed content
   --> src/connection.rs:417:48
    |
417 |             Ok(event) => Ok(Async::Ready(Some((self.0, event)))),
    |                                                ^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the body at 414:64...
   --> src/connection.rs:414:65
    |
414 |       fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
    |  _________________________________________________________________^ starting here...
415 | |         let res = self.0.recv_event();
416 | |         match res {
417 | |             Ok(event) => Ok(Async::Ready(Some((self.0, event)))),
418 | |             Err(e) => Err(e),
419 | |         }
420 | |     }
    | |_____^ ...ending here
note: ...so that types are compatible (expected futures::Stream, found futures::Stream)
   --> src/connection.rs:414:65
    |
414 |       fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
    |  _________________________________________________________________^ starting here...
415 | |         let res = self.0.recv_event();
416 | |         match res {
417 | |             Ok(event) => Ok(Async::Ready(Some((self.0, event)))),
418 | |             Err(e) => Err(e),
419 | |         }
420 | |     }
    | |_____^ ...ending here

我放弃了,我认为这是不可能的。我是对的吗?

0 个答案:

没有答案