从async fn返回的期货的具体类型是什么? [英] What is the concrete type of a future returned from `async fn`?

查看:90
本文介绍了从async fn返回的期货的具体类型是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该使用哪种类型的向量来存储期货?

What type should I use for a vector that stores futures?

我试图在同一URL上进行多个并发请求,并将所有期货保存到向量中,以供join_all使用.

I tried to make multiple concurrent requests on the same URL and save all the futures into the vector to use with join_all.

如果我没有显式设置vector的类型,则一切正常.我知道Rust可以找到正确的变量类型. CLion将向量类型确定为Vec<dyn Future<Output = ()>>,但是当我尝试自己设置向量类型时,会给我一个错误:

If I don't set a type for the vector explicitly, everything works. I understand that Rust can find the proper type of a variable. CLion determines the vector type as Vec<dyn Future<Output = ()>>, but when I try to set the type by myself, it gives me an error:

error[E0277]: the size for values of type `dyn core::future::future::Future<Output = ()>` cannot be known at compilation time
  --> src/lib.rs:15:23
   |
15 |     let mut requests: Vec<dyn Future<Output = ()>> = Vec::new();
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn core::future::future::Future<Output = ()>`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required by `std::vec::Vec`

我必须将类型声明为Vec<Pin<Box<dyn Future<Output=()>>>>,这迫使我将函数的结果包装到requests.push(Pin::from(Box::new(request(i))));

I must declare the type as Vec<Pin<Box<dyn Future<Output=()>>>> which forces me to wrap result of function into requests.push(Pin::from(Box::new(request(i))));

use futures::future::join_all;
use std::future::Future;
use std::pin::Pin;

async fn request(n: i32) {
    println!("Started: {}", n);
    let response = reqwest::get("https://www.rust-lang.org")
        .unwrap()
        .text()
        .unwrap();
    println!("Completed: {}. Response: {}", n, &response[0..10]);
}

async fn main() {
    let mut requests: Vec<dyn Future<Output = ()>> = Vec::new();
    for i in 0..5 {
        requests.push(request(i));
    }
    join_all(requests).await;
}

应该输入哪种类型?

推荐答案

来自 RFC :

异步函数的返回类型是由编译器生成的唯一匿名类型,类似于闭包的类型.您可以认为此类型就像枚举,对于函数的每个屈服点"都有一个变体-它的开头,await表达式和每个返回.每个变体都存储从该屈服点恢复控制所需的状态.

The return type of an async function is a unique anonymous type generated by the compiler, similar to the type of a closure. You can think of this type as being like an enum, with one variant for every "yield point" of the function - the beginning of it, the await expressions, and every return. Each variant stores the state that is needed to be stored to resume control from that yield point.

调用该函数时,此匿名类型在其函数中返回 初始状态,其中包含此函数的所有参数.

When the function is called, this anonymous type is returned in its initial state, which contains all of the arguments to this function.

由于它是匿名类型,因此无法显式声明Future的具体类型.作为API用户,我们只需要知道它实现了std::futures::Future,但这并不意味着我们不需要更深入地了解这种匿名类型及其实现,对于掌握这一概念将是一件很高兴的事情./p>


You can't explicitly declare the concrete type of a future since it is an anonymous type. As an API user we only need to know that it implements std::futures::Future but this doesn't mean that we don't need a deeper knowledge of this anonymous type and it's implementation, it would be nice to have for grasping the concept.

CLion将向量类型确定为Vec<dyn Future<Output = ()>>

这是类型提示,而不是实际类型,因为编译器无法知道dyn Future<Output = ()>的大小,因此将不会对其进行编译.

This is a type hint, not the actual type, since compiler is not able to know the size of dyn Future<Output = ()>, it will not be compiled.

Pin<Box<_>>-使用Future声明显式类型可能不是一个好主意.在您的情况下,这是不需要的,因为从async fn返回的具体类型是相同的.让编译器推断类型就可以了.

Pin<Box<_>>-ing a Future to declare an explicit type might not be a good idea. In your case it's not needed because the concrete types returned from async fn are identical. Letting the compiler infer the type will just be fine.

另请参见:

  • For various concrete return types : How can I put an async function into a map in Rust?
  • Static & Dynamic dispatch : Trait Objects

这篇关于从async fn返回的期货的具体类型是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆