Asynchronous 在async Rust中,如何实现轮询包装器?

Asynchronous 在async Rust中,如何实现轮询包装器?,asynchronous,rust,async-await,future,Asynchronous,Rust,Async Await,Future,假设我有一个异步函数foo,它返回一些值。每次调用后返回的值都不同(例如,从文件或随机数生成器中读取数据块的内容) 我想围绕实现的foo实现一个包装器结构。包装器从foo读取值,以某种方式处理它们,然后将它们放入用户提供的缓冲区 以下是我尝试过的: use futures::io::AsyncRead; 使用pin_utils::pin_mut; 使用std::io; 使用std::pin::pin; 使用std::task::Context; 使用std::task::Poll; 异步fn f

假设我有一个异步函数
foo
,它返回一些值。每次调用后返回的值都不同(例如,从文件或随机数生成器中读取数据块的内容)

我想围绕实现的
foo
实现一个包装器结构。包装器从
foo
读取值,以某种方式处理它们,然后将它们放入用户提供的缓冲区

以下是我尝试过的:

use futures::io::AsyncRead;
使用pin_utils::pin_mut;
使用std::io;
使用std::pin::pin;
使用std::task::Context;
使用std::task::Poll;
异步fn foo()->u8{
b'x'
}
pub-structfooreader;
FooReader的impl异步读取{

fn poll_read(self:Pin,ctx:&mut Context出于某种原因,
Future
特性不在标准前奏中,因此在调用函数之前必须
使用它(提示就在那里,隐藏在所有其他编译器错误之间):

那么,是的,你必须在使用前锁定未来。在你的情况下,最简单的方法是使用
pin_mut!
,它使用了一种有趣的语法:

let f = foo();
pin_mut!(f);
现在,您可以调用
poll()
,但请记住,您必须转发
上下文
参数:

match f.poll(ctx) {
使用工作代码

关于存储未来或放弃未来,你可以做任何你想做的事情,这取决于确切的语义。我个人希望你保持未来并将其运行到完成,除非文档中有明确的说明

当然,如果将未来存储在结构中,
pin_mut!
将不起作用,因为它会使用其参数。您需要将其保存在
pin
中,或者从
self
投影pin,因为它已经被固定

要保留
Pin
,请执行以下操作:

pub struct FooReader {
    f: Option<Pin<Box<dyn Future<Output=u8>>>>,
}
在再次调用
foo()
之前,您可能需要检查一下self.f
,但您已经明白了


pin投影选项更好,因为您避免了额外的盒子分配,但它更复杂,需要额外的板条箱或一些不安全的代码。如果您真的感兴趣,我认为它本身就应该有一个新问题。

出于某种原因,
未来
特性不在标准前奏中,因此您必须
在调用函数之前使用它(提示就在那里,隐藏在所有其他编译器错误之间):

那么,是的,你必须在使用前锁定未来。在你的情况下,最简单的方法是使用
pin_mut!
,它使用了一种有趣的语法:

let f = foo();
pin_mut!(f);
现在,您可以调用
poll()
,但请记住,您必须转发
上下文
参数:

match f.poll(ctx) {
使用工作代码

关于存储未来或放弃未来,你可以做任何你想做的事情,这取决于确切的语义。我个人希望你保持未来并将其运行到完成,除非文档中有明确的说明

当然,如果将未来存储在结构中,
pin_mut!
将不起作用,因为它会使用其参数。您需要将其保存在
pin
中,或者从
self
投影pin,因为它已经被固定

要保留
Pin
,请执行以下操作:

pub struct FooReader {
    f: Option<Pin<Box<dyn Future<Output=u8>>>>,
}
在再次调用
foo()
之前,您可能需要检查一下self.f
,但您已经明白了


pin投影选项更好,因为您可以避免额外的盒子分配,但它更复杂,需要额外的板条箱或一些不安全的代码。如果您真的感兴趣,我认为它本身就应该有一个新问题。

foo
的返回类型是
impl Future时,如何使用pin投影e> ?这是一种我无法在字段声明中表达的类型,因此我将被迫使用
@user16538:你是对的,如果调用
foo()
从内部
poll
。我假设您的真实代码可能从外部
FooReader
获取该值,然后您可以使整个结构在该类型上通用。
FooReader
。当
foo
的返回类型是
impl Future
时,如何使用pin投影?这是一种我无法使用的类型t express在我的字段声明中,因此我将被迫使用
@user16538:你是对的,如果你调用
foo(),你就不能这样做
从内部
poll
。我假设您的真实代码可能从外部
FooReader
获取该值,然后您可以使整个结构在该类型上通用。
FooReader