在async中,Pinning 确保对象不会被move, 这个如何理解?

    1. let fut_one = ...;
    2. let fut_two = ...;
    3. async move {
    4. fut_one.await;
    5. fut_two.await;
    6. }

    实际上这会生成一个匿名struct, AsyncFuture

    1. struct AsyncFuture {
    2. fut_one: FutOne,
    3. fut_two: FutTwo,
    4. state: State,
    5. }
    6. // List of states our `async` block can be in
    7. enum State {
    8. AwaitingFutOne,
    9. AwaitingFutTwo,
    10. Done,
    11. }
    12. impl Future for AsyncFuture {
    13. type Output = ();
    14. fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
    15. loop {
    16. match self.state {
    17. State::AwaitingFutOne => match self.fut_one.poll(..) {
    18. Poll::Ready(()) => self.state = State::AwaitingFutTwo,
    19. Poll::Pending => return Poll::Pending,
    20. }
    21. State::AwaitingFutTwo => match self.fut_two.poll(..) {
    22. Poll::Ready(()) => self.state = State::Done,
    23. Poll::Pending => return Poll::Pending,
    24. }
    25. State::Done => return Poll::Ready(()),
    26. }
    27. }
    28. }
    29. }

    当poll第一次执行,会先poll fut_one, 如果fut_one没有完成, poll将立即返回,假如在async block中, 用了引用会如何?

    1. async {
    2. let mut x = [0; 128];
    3. let read_into_buf_fut = read_into_buf(&mut x);
    4. read_into_buf_fut.await;
    5. println!("{:?}", x);
    6. }
    7. struct ReadIntoBuf<'a> {
    8. buf: &'a mut [u8], // points to `x` below
    9. }
    10. struct AsyncFuture {
    11. x: [u8; 128],
    12. read_into_buf_fut: ReadIntoBuf<'what_lifetime?>,
    13. }

    ReadIntoBuf future 持有x这个字段的引用,但是如果AsyncFuture被move了,那么x也会被move,因为此时AsyncFuture是x的owner,这时read_into_buf_fut 中所持有的引用将被invalidating. 所以要将Future pin住,不让他move