在async中,Pinning 确保对象不会被move, 这个如何理解?
let fut_one = ...;let fut_two = ...;async move {fut_one.await;fut_two.await;}
实际上这会生成一个匿名struct, AsyncFuture
struct AsyncFuture {fut_one: FutOne,fut_two: FutTwo,state: State,}// List of states our `async` block can be inenum State {AwaitingFutOne,AwaitingFutTwo,Done,}impl Future for AsyncFuture {type Output = ();fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {loop {match self.state {State::AwaitingFutOne => match self.fut_one.poll(..) {Poll::Ready(()) => self.state = State::AwaitingFutTwo,Poll::Pending => return Poll::Pending,}State::AwaitingFutTwo => match self.fut_two.poll(..) {Poll::Ready(()) => self.state = State::Done,Poll::Pending => return Poll::Pending,}State::Done => return Poll::Ready(()),}}}}
当poll第一次执行,会先poll fut_one, 如果fut_one没有完成, poll将立即返回,假如在async block中, 用了引用会如何?
async {let mut x = [0; 128];let read_into_buf_fut = read_into_buf(&mut x);read_into_buf_fut.await;println!("{:?}", x);}struct ReadIntoBuf<'a> {buf: &'a mut [u8], // points to `x` below}struct AsyncFuture {x: [u8; 128],read_into_buf_fut: ReadIntoBuf<'what_lifetime?>,}
ReadIntoBuf future 持有x这个字段的引用,但是如果AsyncFuture被move了,那么x也会被move,因为此时AsyncFuture是x的owner,这时read_into_buf_fut 中所持有的引用将被invalidating. 所以要将Future pin住,不让他move
