如何在不阻塞的情况下偷看频道并且仍然能够检测到挂断?

How to peek on channels without blocking and still being able to detect hangup?

根据 Rust Receiver 结尾的 .try_iter() 方法的文档 std::mpsc::channel,我知道这个迭代器要么产生 "None":

在我的例子中,我想peek进入频道,不阻塞,从而确定是否:

问题是如果我..

match my_receiver.try_iter().peekable().peek() {
    Some(data) => {/* there is data */}
    None => {/* there is no data, but there may be later.. or maybe not, because the channel has maybe hung up, I can't tell! */}
}

..我只能区分两种情况。

我如何才能窥视通道的 receiver 端并区分这三种可能的结果,而不会在有数据时阻止或消耗数据?

你可以使用 try_recv 做你想做的事。

它returns一个Result<T, TryRecvError>TryRecvError可以是EmptyDisconnected

match my_receiver.try_recv() {
    Ok(data) => {/* handle data */}
    Err(TryRecvError::Disconnected) => {/* handle sender disconnected */}
    Err(TryRecvError::Empty) => {/* handle no data available yet */}
}

try_iter() 方法 return 是一个丢弃 Error 值的迭代器,因此您无法区分大小写。

您可以创建自己的迭代器来迭代 Result 而不是丢弃错误值:

pub struct TryIterResult<'a, T: 'a> {
    rx: &'a Receiver<T>,
}

pub fn try_iter_result<'a, T>(rx: &'a Receiver<T>) -> TryIterResult<'a, T> {
    TryIterResult { rx: &rx }
}

impl<'a, T> Iterator for TryIterResult<'a, T> {
    type Item = Result<T, TryRecvError>;

    fn next(&mut self) -> Option<Result<T, TryRecvError>> {
        match self.rx.try_recv() {
            Ok(data) => Some(Ok(data)),
            Err(TryRecvError::Empty) => Some(Err(TryRecvError::Empty)),
            Err(TryRecvError::Disconnected) => None
        }
    }
}

然后您将能够获得一个可窥视的迭代器,它将 return 三个可能的条件:

match try_iter_result(my_receiver).peekable().peek() {
    Some(Ok(data)) =>{ /* there is data */},
    Some(Err(_)) => { /* nothing available right now */ },
    None => {/* disconnected */}
}