Swift:将 AsyncStream 映射到另一个 AsyncStream

标签 swift swift-concurrency

更新

接受的答案没有直接回答原始问题,但帮助解决了我试图解决的根本问题:我想将一个 AsyncStream(它是一个 AsyncSequence)映射到另一个元素类型为 T2 的 AsyncSequence。我在 this comment 中添加了一些细节.

原始问题

我想映射一个 AsyncStream进入另一个AsyncStream .我想知道是否有 .map可以像数组一样使用。

引自Apple documentation :

Creates an asynchronous sequence that maps the given closure over the asynchronous sequence’s elements.

以下代码有错误:

Cannot convert value of type 'AsyncMapSequence<AsyncStream<Int>, Int>' to specified type 'AsyncStream<Int>'

据我了解,是因为.map的返回类型在这种情况下是 AsyncMapSequence<...>而不是 AsyncStream<Int> .

有没有办法只映射 AsyncStream<T1>进入 AsyncStream<T2>具有转换功能 T1 → T2 , 因为它适用于映射 Array<T1>进入Array<T2>

提前致谢!

import SwiftUI

@main
struct MacosPlaygroundApp: App {
    var body: some Scene {
        WindowGroup("Playground") {
            Text("Hello World")
                .padding(100)
                .onAppear {
                    Task {
                        let numStream: AsyncStream<Int> = AsyncStream { continuation in
                            Task {
                                try await Task.sleep(nanoseconds: 1_000_000_000)
                                continuation.yield(0)
                                try await Task.sleep(nanoseconds: 1_000_000_000)
                                continuation.yield(1)
                                try await Task.sleep(nanoseconds: 1_000_000_000)
                                continuation.yield(2)
                                continuation.finish()
                            }
                        }

                        let doubleNumStream: AsyncStream<Int> = numStream.map { num in
                            return 2 * num
                        }

                        for await doubleNum in doubleNumStream {
                            print("Next num is \(doubleNum)")
                        }

                    }
                }
        }
    }
}

最佳答案

你说:

Let's say I have a function, input is some async sequence of data of a certain type T, and for each such T item, it does something with it... For this function, it doesn't matter how that async sequence was calculated, e.g. whether it was mapped from another sequence or not. Ideally I would type it as AsyncSequence<T> (T being a specific type in my actual code), but AsyncSequence doesn't take type parameters.

我建议您定义此函数以使用 AsyncSequence ,例如,这是一个打印序列值的方法:

func printSequence<S: AsyncSequence>(_ sequence: S) async throws where S.Element == Int {
    for try await value in sequence {
        print("Next num is \(value)")
    }
    print("done")
}

这适用于任何 AsyncSequenceInt , 要么是原来的 numStream或映射的 doubleNumStream .

然后,正如 Sweeper 所说,您可以只使用现有的 mapAsyncSequence :

Task {
    let numStream = AsyncStream<Int> { continuation in
        Task {
            try await Task.sleep(nanoseconds: 1_000_000_000)
            continuation.yield(0)
            try await Task.sleep(nanoseconds: 1_000_000_000)
            continuation.yield(1)
            try await Task.sleep(nanoseconds: 1_000_000_000)
            continuation.yield(2)
            continuation.finish()
        }
    }

    let doubleNumStream = numStream.map { num in             // let it just infer the type for you
        return 2 * num
    }

    try await printSequence(doubleNumStream)
}

关于Swift:将 AsyncStream 映射到另一个 AsyncStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73425713/

相关文章:

swift - 从无任务上下文创建常规或分离任务的区别?

Swift 将字符串转换为 UnsafeMutablePointer<Int8>

swift - UIToolBar 设置 isEnabled 从其他 viewControllers

ios - Swift - 在 init() 中使用 UIButton.addTarget 时崩溃

swift - hidesBottomBarWhenPushed 第一次被延迟

swift - 何时将非隔离与参与者的存储属性一起使用?

swift - 通过 RightBarButtonItem 移动到另一个 Viewcontroller

swift - 使用 Swift 并发和观察框架 iOS 17 监听搜索栏随时间变化的值

swift - 无法从标有相同 globalActor 的闭包安全地访问 globalActor 的方法

Swift 5.5并发: Are scheduled Tasks serial to one another