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