如何创建一个流,其中的项目基于该流之前返回的项目?

2024-03-14

我有一个函数可以生成futures::Stream基于一个论点。我想多次调用这个函数并将流压平在一起。使问题变得复杂的是,我想将流返回的值作为参数提供给原始函数。

具体来说,我有一个函数可以将数字流返回到零:

fn numbers_down_to_zero(v: i32) -> impl Stream<Item = i32> {
    stream::iter((0..v).rev())
}

我想从 5 开始调用这个函数。还应该为每个返回的奇数调用该函数。总的调用集numbers_down_to_zero将会:

numbers_down_to_zero(5);
numbers_down_to_zero(3);
numbers_down_to_zero(1);
numbers_down_to_zero(1);

产生总流量

4
3
2
1
0
2
1
0
0
0

有哪些技术可以实现这一点?


你可以用以下方法解决这个问题unfold。您将有一个“状态”结构,它保留“基本流”(在本例中倒数为零)和将生成新流的项目列表,并将其用作参数unfold展开时保持状态。

这样编译器就不必推理生命周期所有权,因为状态可以移动到async每次调用闭包时都会阻塞。

/// Base stream (counting down to zero).
fn f(n: i32) -> impl Stream<Item = i32> {
    stream::iter((0..n).rev())
}

/// "Recursive" stream
fn g(n: i32) -> impl Stream<Item = i32> {
    /// Helper struct to keep state while unfolding
    struct StreamState<S> {
        inner_stream: S,
        item_queue: VecDeque<i32>,
    }

    // Build helper struct
    let state = StreamState {
        inner_stream: f(n),
        item_queue: VecDeque::new(),
    };

    // Unfold with state
    stream::unfold(state, |mut state| async move {
        loop {
            if let Some(item) = state.inner_stream.next().await {
                // Iterate inner stream, and potentially push item to queue
                if item % 2 == 1 {
                    state.item_queue.push_front(item);
                }
                break Some((item, state));
            } else if let Some(item) = state.item_queue.pop_back() {
                // If inner stream is exhausted, produce new stream from queue
                // and repeat loop
                state.inner_stream = f(item);
            } else {
                // If queue is empty, we are done
                break None;
            }
        }
    })
}

StreamExt::next https://docs.rs/futures/0.3.1/futures/stream/trait.StreamExt.html#method.next要求内部流实现Unpin,因此它不能用于任意流。您可以随时使用Box::pin(stream)相反,因为Pin<Box<T>> is Unpin并实施Stream if T: Stream.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建一个流,其中的项目基于该流之前返回的项目? 的相关文章

随机推荐

  • Android 4.0 -> 4.3(包含) - Web 视图页面之间的 Web 存储丢失

    我正在开发一个 Android 项目 该项目依赖于WebView浏览设备上存储的多个 HTML 页面 并在需要将输入存储到数据库时将输入提交到 Web 视图 每个页面都包含与 jQuery 绑定到上一页 下一页的控件 每个页面包含不同类型的
  • Linux Mach-O 反汇编器

    是否有任何 Linux 程序可以像 objdump 一样反汇编 OSX 通用 x86 x86 64 fat Mach O 二进制文件 GNU binutils 的 objdump 支持 ELF 和 Windows PE 文件 但不支持 Ma
  • 什么是对象关系映射框架? [复制]

    这个问题在这里已经有答案了 正如标题所说 什么是 ORM 框架以及它有什么用处 一个简单的答案是 您可以使用编程语言将表或存储过程包装在类中 这样您就可以使用对象的方法和属性 而不是编写 SQL 语句来与数据库交互 换句话说 而不是这样的
  • 如何使用负 z-index 使链接可点击?

    我在用drop down我的标题中的菜单用于通知 但是当下拉打开所有可见的 div 后面时 我给了z index到所有 div 但这些 div 上的链接现在不可点击 下拉 div CSS drop down overflow scroll
  • 未捕获错误:语法错误,无法识别的表达式:悬停

    这是问题的 JSFidle http jsfiddle net LRTh3 36 http jsfiddle net LRTh3 36 div boxes mousedown function event Error on this lin
  • Cognito / S3 用户特定策略

    我使用适用于 Android 的 AWS 开发工具包和 Cognito 对我的 AWS 资源的用户进行身份验证 通过 Amazon 登录 我是什么尝试要做的就是设置一个 S3 存储桶 如下所示 my bucket email protect
  • pydantic 和抽象类的子类

    我正在尝试将 pydantic 与如下所示的架构一起使用 class Base BaseModel ABC common int class Child1 Base child1 int class Child2 Base child2 i
  • Java 中防御性副本的低效[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我是一名长期 C C 程序员 正在学习 Java 我读过有关通过使用返回对私有字段的引用的访问器方法来破坏封装的问题 标准的Java解决方案似乎
  • 无法删除/取消链接到 python 和 windows 中的目录的符号链接

    edited 我在 Widnows7 上创建了指向目录的符号链接 使用mklink命令行 mklink d books config 我正在尝试使用 python 2 7 删除它 仍在 Windows 上 gt gt gt os remov
  • 在 ASP.NET Web 表单中创建动态 UI

    我需要创建一个调查页面 其中包含从数据库读取的以下结构 Survey QuestionA a Answer1 Radio button b Answer2 Radio button c Answer3 Radio button d Answ
  • 包标识符应该是小写还是驼峰?

    假设我有一个名为 Foo Bar 的应用程序 包标识符应该是com tyilo foobar or com tyilo FooBar 什么是最正常的 苹果是怎么做的 您可以做任何事情 但为了让生活更简单并防止常见错误 将其全部小写更容易 但
  • 在本地计算机上使用 Github 操作秘密 - 可能吗?

    我知道我可以使用curl 来通过curl 列出存储库的秘密 如下所示 curl H Accept application vnd github v3 json H Authorization token personal access to
  • Python 寻找素因数

    两部分问题 试图确定 600851475143 的最大质因数 我在网上发现了这个程序似乎有效 问题是 尽管我了解该程序正在做什么的基础知识 但我很难弄清楚它到底是如何工作的 另外 我希望您能阐明您可能知道的寻找素因数的任何方法 也许无需测试
  • Visual Studio 2010 的 HWnd

    有没有办法从 VSIX 扩展获取指向 Visual Studio 2010 顶部窗口的 HWnd 指针 我想更改窗口的标题 由于您的 VSIX 扩展很可能会与 Visual Studio 一起在进程内运行 因此您应该尝试以下操作 Syste
  • fork:关闭所有打开的套接字

    我在用multiprocessing Pool map 它分叉当前进程 我的理解是 默认情况下 所有文件描述符包括插座分叉时从主进程复制 主进程本身是一个Web服务器 使用cherrypy http cherrypy org 所以这会对开放
  • 需要在 bootstrap css 中单击时将图像加载为模态

    我尝试通过淡入淡出背景来加载模态图像 这个对我有用 但是对于多个图像 如何在不编写多个模态 div 的情况下根据图像 id 加载我单击的图像
  • VB 2010 中的对象是否获得了与 C# 4.0 中的动态相同的优化?

    有些人认为 C 4 0 引入的功能dynamic关键字与VB的 一切都是对象 特性相同 但是 对动态变量的任何调用都将被转换为委托一次 从那时起 将调用该委托 在VB中 当使用Object 不应用缓存 并且对非类型化方法的每次调用都涉及大量
  • 使用 helm 在 kubernetes 集群中运行 Nexus

    有一个 Nexus 的舵图 https github com helm charts tree master stable sonatype nexus https github com helm charts tree master st
  • 关于Future.firstCompletedOf和Garbage Collect机制

    I ve encountered this problem in my real life project and proved by my testing code and profiler Instead of pasting tl d
  • 如何创建一个流,其中的项目基于该流之前返回的项目?

    我有一个函数可以生成futures Stream基于一个论点 我想多次调用这个函数并将流压平在一起 使问题变得复杂的是 我想将流返回的值作为参数提供给原始函数 具体来说 我有一个函数可以将数字流返回到零 fn numbers down to