0

I'm ramping up on Rust from a Java/C background. Pretty happy so far. One thing that keeps getting in my way is the implicit type signatures on variables. I know the compiler knows the type of each variable, but it will often help improve my understanding if I also know :)

I'm currently uses CLion with the Rust plugin. It does a decent job with Rust, but the "extract expression to variable" action, which I frequently use to remind myself of the type of an expression, uses implicit type signatures for Rust.

For example, I am really curious what the type signature is for a vector of Futures, because the Future trait has a type parameter and I've never seen one written out before. The Book didn't have any ready examples for me either, unfortunately.

let requests = endpoints.iter()
                        .map(|endpoint| client.get(format!("..{}..",..endpoint..)).send())
                        .collect();

I know this is a vector of futures that will yield a Result containing either a Response or an Error. I just don't know how to express that yet.

let requests : Vec<Future<Output=Result<Response,reqwest::Error>>> = ...

error[E0277]: the size for values of type `dyn std::future::Future<Output = std::result::Result<reqwest::async_impl::response::Response, reqwest::error::Error>>` cannot be known at compilation time

let requests : Vec<impl Future<Output=Result<Response,reqwest::Error>>> = ...

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
let requests : Vec<Future<Result<Response,reqwest::Error>>> = ...

error[E0107]: wrong number of type arguments: expected 0, found 1
let requests : Vec<impl Future<Result<Response, reqwest::Error>>> = ...

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
let requests : Vec<Box<dyn Future<Output = Result<Response, reqwest::Error>>>> = ...
            .map(Box::new)
            .collect()

error[E0277]: a collection of type `std::vec::Vec<std::boxed::Box<dyn std::future::Future<Output = std::result::Result<reqwest::async_impl::response::Response, reqwest::error::Error>>>>` cannot be built from an iterator over elements of type `std::boxed::Box<impl std::future::Future>`

Huckle
  • 1,810
  • 3
  • 26
  • 40
  • @ÖmerErden Almost. I get that there's no single Future struct / that the implementations of future are generated at compile time. That answer doesn't go far enough to explain what I would need to do to make a collection of Futures. The various anonymous Future implementations all share a common Trait, so I should be able to make a collection of them. Vec seems to be the wrong one, because it wants Sized contents (and since each Future can be a different size, that will never work). Is there a collection that doesn't require Sized? – Huckle Mar 13 '20 at 05:55
  • Actually it was also linked in the see also section, here is the link : https://stackoverflow.com/questions/58704424/how-can-i-put-an-async-function-into-a-map-in-rust/58709332 – Ömer Erden Mar 13 '20 at 05:57
  • Any collection not requiring Sized must use indirection at some level. Think about it: You need to know the size of each element of a collection in order to be able to lay it out in memory. Making those details explicit, this is one of rusts strengths. You want to use indirection, so you need to use a pointer of some kind, with the obvious choice being Box. – L. Riemer Mar 13 '20 at 08:37
  • The `send()` method returns `impl Future<...>`, which is an arbitrary concrete type implementing the `Future` trait. The concrete type itself cannot be named, so the best type annotation you can add is `Vec<_>`. Once the [`impl_trait_in_bindings` feature](https://doc.rust-lang.org/unstable-book/language-features/impl-trait-in-bindings.html) is stable, you will be able to use your second attempt. – Sven Marnach Mar 13 '20 at 13:14

0 Answers0