代码之家  ›  专栏  ›  技术社区  ›  Camden Narzt

如何在不移动self的情况下消除混合迭代器和Futures调用链的歧义?

  •  -2
  • Camden Narzt  · 技术社区  · 6 年前

    我正在尝试添加期货 Stream 对已同步的现有结构的实现 Iterator 实施。为了保持代码干燥,我想修改 迭代器 实现调用新的 河流 实现并等待它。

    我模拟了 迭代器 之后 the code sample for Stream::by_ref :

    stream.by_ref().take(2)
    

    我的实现结果是这样的:

    impl Iterator for Websocket {
        type Item = Message;
    
        fn next(&mut self) -> Option<Self::Item> {
            self.by_ref().take(1).wait().next().and_then(Result::ok)
        }
    }
    

    但是,我得到了多个适用项的错误:

    error[E0034]: multiple applicable items in scope
       --> src/websocket/websocket.rs:330:14
        |
    330 |         self.by_ref().take(1).wait().next().and_then(Result::ok)
        |              ^^^^^^ multiple `by_ref` found
        |
    note: candidate #1 is defined in an impl of the trait `websocket::websocket::futures::Stream` for the type `websocket::websocket::Websocket`
       --> src/websocket/websocket.rs:149:1
        |
    149 | impl Stream for Websocket {
        | ^^^^^^^^^^^^^^^^^^^^^^^^^
    note: candidate #2 is defined in an impl of the trait `std::iter::Iterator` for the type `websocket::websocket::Websocket`
       --> src/websocket/websocket.rs:324:1
        |
    324 | impl Iterator for Websocket {
        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    note: candidate #3 is defined in the trait `std::io::Write`
        = help: to disambiguate the method call, write `std::io::Write::by_ref(&mut self)` instead
    

    我想从左到右调用的方法是:

    如果我消除代码的歧义,它看起来是这样的:

    impl Iterator for Websocket {
        type Item = Message;
    
        fn next(&mut self) -> Option<Self::Item> {
            <Self as Stream>::take(*<Self as Stream>::by_ref(self),1).wait().next().and_then(Result::ok)
        }
    }
    

    但是,我会得到一个终身错误:

    error[E0507]: cannot move out of borrowed content
       --> src/websocket/websocket.rs:331:32
        |
    331 |         <Self as Stream>::take(*<Self as Stream>::by_ref(self),1).wait().next().and_then(Result::ok)
        |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
    

    我该怎么做才能让这个不含糊,但保持呼叫的能力 take 关于结果 by_ref ?

    我知道有一个新版本的Futures,但是我不能使用它,因为我使用的其他库需要与我使用的Futures版本兼容的API。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Shepmaster Tim Diekmann    6 年前

    您可以通过不尝试移出借用价值来避免移出借用价值:

    extern crate futures;
    
    use futures::prelude::*;
    
    struct Message;
    struct Websocket;
    
    impl Stream for Websocket {
        type Item = Message;
        type Error = ();
    
        fn poll(&mut self) -> Result<Async<Option<Self::Item>>, Self::Error> {
            Err(())
        }
    }
    
    impl Iterator for Websocket {
        type Item = Message;
    
        fn next(&mut self) -> Option<Self::Item> {
            let a = Stream::take(self, 1);
            let mut b = a.wait();
            let c = Iterator::next(&mut b);
            c.and_then(Result::ok)
        }
    }
    
    fn main() {}
    

    没必要打电话 Stream::by_ref 因为起始类型已经是 &mut Websocket ,所以我把它移走了。

    如果需要,可以将它们重新组合为一行:

    fn next(&mut self) -> Option<Self::Item> {
        Stream::take(self, 1)
            .wait()
            .next()
            .and_then(Result::ok)
    }