如何将 Stream::map 与返回 Result 的函数一起使用?

Jam*_*kin 5 future rust

我有以下代码(请参阅游乐场):

use futures::{stream, Future, Stream}; // 0.1.25
use std::num::ParseIntError;

fn into_many(i: i32) -> impl Stream<Item = i32, Error = ParseIntError> {
    stream::iter_ok(0..i)
}

fn convert_to_string(number: i32) -> Result<String, ParseIntError> {
    Ok(number.to_string())
}

fn main() {
    println!("start:");
    let vec = into_many(10)
        .map(|number| convert_to_string(number))
        .collect()
        .wait()
        .unwrap();

    println!("vec={:#?}", vec);

    println!("finish:");
}
Run Code Online (Sandbox Code Playgroud)

它输出以下内容(即Vec<Result<i32, ParseIntError>>):

use futures::{stream, Future, Stream}; // 0.1.25
use std::num::ParseIntError;

fn into_many(i: i32) -> impl Stream<Item = i32, Error = ParseIntError> {
    stream::iter_ok(0..i)
}

fn convert_to_string(number: i32) -> Result<String, ParseIntError> {
    Ok(number.to_string())
}

fn main() {
    println!("start:");
    let vec = into_many(10)
        .map(|number| convert_to_string(number))
        .collect()
        .wait()
        .unwrap();

    println!("vec={:#?}", vec);

    println!("finish:");
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让它输出 aVec<i32>并且如果发生任何错误则立即停止执行并从函数返回(例如,像这个例子)?

注意:我确实想使用,use futures::Stream; // 0.1.25即使它对于这个特定的例子没有意义。

小智 2

以下代码(游乐场链接)作为问题中当前代码的修改得到了您想要的结果:

use futures::{stream, Future, Stream}; // 0.1.25
use std::num::ParseIntError;

fn into_many(i: i32) -> impl Stream<Item = i32, Error = ParseIntError> {
    stream::iter_ok(0..i)
}

fn convert_to_string(number: i32) -> Result<String, ParseIntError> {
    Ok(number.to_string())
}

fn main() {
    println!("start:");
    let vec: Result<Vec<String>, ParseIntError> = into_many(10)
        .map(|number| convert_to_string(number))
        .collect()
        .wait()
        .unwrap()
        .into_iter()
        .collect();

    println!("vec={:#?}", vec);

    println!("finish:");
}
Run Code Online (Sandbox Code Playgroud)

由于您当前的代码返回了 a Vec,我们可以将其转换为迭代器并将其收集为您想要的类型。需要类型注释,以便收集知道将迭代器收集到什么类型。

请注意,特征上collect的方法Iterator不要与.collectStream

最后,虽然这有效,但它可能并不完全是您想要的,因为它仍然等待流中的所有结果收集到向量中,然后再使用收集来转换向量。我没有期货经验,所以不确定这有多大可能(可能是,但可能需要不太简洁的函数式编程风格解决方案)。