MST

星途 面试题库

面试题:Rust异步编程中的Future和Poll

请解释Rust异步编程中`Future`和`Poll`的概念及其关系。并举例说明如何手动实现一个简单的`Future`,使用`Poll`来管理其状态转变。
29.8万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Future概念

在Rust异步编程中,Future是一个代表异步计算的类型。它描述了一个可能尚未完成的操作,并且可以通过poll方法查询其状态。Future trait定义如下:

trait Future {
    type Output;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

FutureOutput关联类型表示异步操作完成时返回的类型。

Poll概念

Poll是一个枚举,用于表示Future的状态。它定义在std::task模块中:

pub enum Poll<T> {
    Ready(T),
    Pending,
}
  • Poll::Ready(T):表示Future已经完成,并且返回值为T
  • Poll::Pending:表示Future尚未完成,需要再次轮询。

FuturePoll的关系

Futurepoll方法返回一个Poll值,用于告知调用者Future的当前状态。调用者(例如async运行时)会根据返回的Poll值来决定下一步操作。如果返回Poll::Pending,调用者会在适当的时候再次调用poll方法,直到返回Poll::Ready

手动实现简单Future示例

use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

// 定义一个简单的Future结构体
struct MyFuture {
    state: i32,
}

// 实现Future trait
impl Future for MyFuture {
    type Output = i32;

    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = self.get_mut();
        if this.state < 10 {
            this.state += 1;
            Poll::Pending
        } else {
            Poll::Ready(this.state)
        }
    }
}

fn main() {
    let mut future = MyFuture { state: 0 };
    let mut context = std::task::Context::from_waker(&std::task::noop_waker());
    loop {
        match future.as_mut().poll(&mut context) {
            Poll::Ready(result) => {
                println!("Future completed with result: {}", result);
                break;
            }
            Poll::Pending => {
                println!("Future is still pending");
            }
        }
    }
}

在这个例子中,MyFuture结构体实现了Future trait。poll方法根据state的值决定返回Poll::Pending还是Poll::Ready。在main函数中,手动轮询MyFuture,直到它返回Poll::Ready