Rust existential type

x1957

x1957

Posted on July 19, 2019

Rust existential type

最近在封装一点lib,本来想在trait里面定义async fn的,但是目前来说是不允许的.Async Methods I: generic associated types,只能想其他办法咯,那我们就再调用async fn返回个future吧,也一样的。

然后问题又来了,本来想是return 一个 impl Future,但是。。。trait里面又不允许,sad!

Async Methods I: generic associated types这里也解释了为什么直接associated types不行。

原因就是async返回的Future是个闭包,把所有东西的lifetime都丢进去了,如果我们要写associated types需要这样:

trait Foo {
    type _Future<'a>: Future<Output = i32> + 'a;
    fn foo_method<'a>(&'a self) -> Self::_Future<'a>;
}

但是呢。。。问题又来了,目前associated types不支持lifetime参数,这个东西叫generic associated types

不过还好,我们还有existential type,参考RFC

#![feature(async_await, existential_type)]

use futures::compat::Future01CompatExt;
use futures::compat::Stream01CompatExt;
use futures::future::{FutureExt, TryFutureExt};
use futures::stream::{StreamExt, TryStreamExt};
use futures::Future;
use reqwest::r#async::{Client, ClientBuilder, Decoder};
use std::io::{self, Write};

trait Fuck {
    type AsyncResult: Future<Output=()>;
    fn download(&self) -> Self::AsyncResult;
}

struct Down;

impl Down {
    pub fn new() -> Self{
        Down{}
    }
}

impl Fuck for Down {
    existential type AsyncResult: Future<Output=()>;
    fn download(&self) -> Self::AsyncResult {
        download()
    }
}

async fn download() {
    let client = ClientBuilder::new().build().unwrap();
    let res = client
        .get("https://dev.to/x1957/rust-async-await-2l4c")
        .send()
        .compat()
        .await;
    let mut body = res.unwrap().into_body().compat();
      while let Some(next) = body.next().await {
        let chunk = next.unwrap();
        io::stdout().write_all(&chunk).unwrap();
    }
    println!("\nDone");
}

fn call<T: Fuck>(x: T)->T::AsyncResult {
    x.download()
}

fn main() {
    // let fut = download().unit_error().boxed().compat();
    let fut = call(Down::new()).unit_error().boxed().compat();
    tokio::run(fut);
}

我们定义了Fuck这个trait里面有个associated type AsyncResult,在我们impl这个trait的使用通过existential type来指出AsyncResult是impl Future的即可。

现在使用的时候需要打开feature existential_type

💖 💪 🙅 🚩
x1957
x1957

Posted on July 19, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Rust existential type
rust Rust existential type

July 19, 2019