Future for &mut F {\n type Output = F::Output;\n\n fn poll(mut self: Pin, cx: &mut Context) -> Poll<:output> {\n F::poll(Pin::new(&mut **self), cx)\n }\n}\n\nimpl Future for Pin
\nwhere\n P: Unpin + ops::DerefMut,\n{\n type Output = <::Target as Future>::Output;\n\n fn poll(self: Pin, cx: &mut Context) -> Poll<:output> {\n Pin::get_mut(self).as_mut().poll(cx)\n }\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Pin 類型能夠讓數據在內存中固定。withoutboats 有一篇 "},{"type":"link","attrs":{"href":"https://boats.gitlab.io/blog/post/2018-01-25-async-i-self-referential-structs/","title":null},"content":[{"type":"text","text":"blog"}]},{"type":"text","text":",詳細說明了自引用結構在 MOVE 之後產生的問題。Pin 能夠解決這類問題。在上面的代碼裏面,看到針對 unpin 的類型,也增加了 Pin::new 來保障數據在內存中固定"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Future 的 poll 的第二個參數是 Context 類型,也就是 waker 的封裝。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"rust"},"content":[{"type":"text","text":"fn poll(self: Pin, cx: &mut Context) -> Poll<:output>;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個 Context 用來保存 future 的狀態,在 poll 是 Pending 的時候保存 future 的信息和狀態,在 poll 到 Ready 的時候,再執行。所以在每次 poll 之後,如果發現不是 Ready 的狀態,都會重新把這個 Context 帶入到一個新的 future 等待下次事件觸發調用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Future 和 Pin 構成了 rust async/await 的基礎。在函數前面加上 async ,就把函數包裝稱爲了一個 Future;Future 後面加上 .await,就執行 Future 的 poll 操作。例如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"rust"},"content":[{"type":"text","text":"async fn read_file(path: &str) -> io::Result {\n let mut file = File::open(path).await?;\n let mut contentx = String::new();\n file.read_to_string(&mut contexts).await?;\n Ok(contents)\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"async 在函數前面,把函數包裝爲一個"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"rust"},"content":[{"type":"text","text":"Future