简体   繁体   English

为什么迭代器的实现在异步上下文中不够通用?

[英]Why implementation of iterator is not generic enough in async context?

Cross posting on github github上的交叉发布

Given the following snippet:给定以下代码段:

use futures::stream::{self, StreamExt};

async fn from_bar(bar: &[Vec<&u8>]) {
    let x = bar.iter().flat_map(|i| i.iter().map(|_| async { 42 }));
    let foo: Vec<_> = stream::iter(x).collect().await;
}

#[tokio::main]
async fn main() {
    for bar in vec![] {
        tokio::spawn(async {
            from_bar(bar).await;
        });
    }
}

I get the following errors:我收到以下错误:

error[E0308]: mismatched types
  --> src/main.rs:11:9
   |
11 |         tokio::spawn(async {
   |         ^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected type `std::ops::FnOnce<(&&u8,)>`
              found type `std::ops::FnOnce<(&&u8,)>`

error: implementation of `std::iter::Iterator` is not general enough
    --> src/main.rs:11:9
     |
11   |           tokio::spawn(async {
     |           ^^^^^^^^^^^^ implementation of `std::iter::Iterator` is not general enough
     |
     = note: `std::iter::Iterator` would have to be implemented for the type `std::slice::Iter<'0, &u8>`, for any lifetime `'0`...
     = note: ...but `std::iter::Iterator` is actually implemented for the type `std::slice::Iter<'1, &u8>`, for some specific lifetime `'1`

I was expecting no error because the lifetimes seem to be correct to me.我期待没有错误,因为生命周期对我来说似乎是正确的。 Note that removing main() or removing the code inside from_bar() both eliminate the errors.请注意,删除main()或删除from_bar()中的代码都可以消除错误。 Not only that, the error messages are also very strange.不仅如此,错误信息也很奇怪。 They may be related to a regression in the compiler , though more than that they seem to be in the wrong place ( maybe related ).它们可能与编译器中的回归有关,尽管它们似乎在错误的位置(可能相关)。

Version rustc 1.43.0 (4fb7144ed 2020-04-20) :版本rustc 1.43.0 (4fb7144ed 2020-04-20)

[dependencies]
futures = '0.3.1'

[dependencies.tokio]
version = '0.2'
features = ['full']

Slightly simpler reproduction:稍微简单的复制:

use futures::stream::{self, StreamExt};

async fn from_bar(bar: &[Vec<&u8>]) {
    let x = bar.iter().flat_map(|i| i.iter().map(|_| async { 42 }));
    let foo: Vec<_> = stream::iter(x).collect().await;
}

#[tokio::main]
async fn main() {
    tokio::spawn(async {
        from_bar(&vec![]).await;
    });
}

playground . 游乐场

This example makes what's wrong clearer: the reference that you pass to from_bar only lives until the end of main (or possibly even the current loop iteration in your example), but spawn needs it to live longer than that since the spawned task may run longer.这个例子让问题更清楚了:你传递给from_bar的引用只存在到main结束(或者甚至可能是你的例子中的当前循环迭代),但是spawn需要它比这更长的时间,因为生成的任务可能运行更长时间.

What I don't understand is how this translates into the error message we get…我不明白的是这如何转化为我们得到的错误信息......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM