當使用一個新的軟件時,我發現在潛入太深之前閱讀文檔非常有用。一般來說,Rust社區提供了相當不錯的資源。
例如,除了selection of working examples之外,Tokio項目還有一個entire page talking about Stream
s and Sink
s。 generated API documentation for Sink
也是非常寶貴的。
我推薦所有新程序員學會做的另一件事是創建一個MCVE的問題。這使他們能夠專注於問題的核心,同時還能夠消除問題背後的言辭和磨礪。這裏有一個這種情況:
extern crate futures;
fn thing<S>(sink: S)
where S: futures::Sink<SinkItem = i32>,
{
let mut all_the_things = vec![1, 2, 3, 4, 5];
while let Some(v) = all_the_things.pop() {
sink.send(v);
}
}
fn main() {}
我們得到錯誤信息
error[E0382]: use of moved value: `sink`
--> src/main.rs:9:9
|
9 | sink.send(v);
| ^^^^ value moved here in previous iteration of loop
|
= note: move occurs because `sink` has type `S`, which does not implement the `Copy` trait
讓我們回頭API文檔...
fn send(self, item: Self::SinkItem) -> Send<Self>
where Self: Sized
從這一點,我們可以看到,send
消耗接收器並返回一個Send
對象。這很奇怪,不是嗎!實際上並不奇怪,一旦你看到Send
實現Future
- 將某些內容推入流中可能會阻塞流是否已滿;這是背壓的概念。結果爲Future
是您如何知道該項目何時實際添加到流中。 Future
的執行Send
有Item = S
,Sink
的具體類型。因此一個解決方案是推動未來完成獲得匯回來,這樣做的一個方法是調用wait
:
use std::fmt;
use futures::Future;
fn thing<S>(mut sink: S)
where S: futures::Sink<SinkItem = i32>,
S::SinkError: fmt::Debug,
{
let mut all_the_things = vec![1, 2, 3, 4, 5];
while let Some(v) = all_the_things.pop() {
let f = sink.send(v);
sink = f.wait().expect("Something bad happened while sending");
}
}
這編譯,但不是超級靚。回到文檔,我們也可以看到Sink::send_all
,這需要Stream
。我們可以通過使用stream::iter
創建一個迭代器Stream
:
fn thing<S>(sink: S)
where S: futures::Sink<SinkItem = i32>,
S::SinkError: fmt::Debug,
{
let all_the_things = vec![1, 2, 3, 4, 5];
let wrapped = all_the_things.into_iter().map(Result::Ok);
sink.send_all(futures::stream::iter(wrapped)).wait().expect("Something bad happened while sending");
}
我們再次使用wait
帶動未來完成。如果我們忘記了一個很好的錯誤:「期貨什麼也不做,除非被調查」。但是,wait
並不是真正處理此問題的正確方法。通常,您想要將Future
返回給調用者,因爲他們想要知道什麼時候所有東西都被推入水槽。
*「以下顯然不起作用*」 - 怎麼樣?你可以包括錯誤,或描述你看到的行爲? –
在提出有關堆棧溢出的問題時,請生成一個[MCVE]。 – Shepmaster
我敢打賭,**缺少的錯誤信息**說了一些關於*期待'T',找到了'&T' *。如果是這樣的話,我強烈建議你回頭閱讀[* The Rust Programming Language *](https://doc.rust-lang.org/stable/book/),因爲這不會是關於Tokio的問題,而是Rust的基本所有權。 – Shepmaster