StreamUtilities

StreamUtilities 是一个工具箱,为 Swift 中的流操作提供两个实用工具

概述

SyncStream

AsyncStream 提供了一种便捷的方法,可以通过调用 continuation 的闭包来创建序列以生成元素。然而,在某些情况下,您可能需要使用闭包同步生成序列。为了满足这种需求,我们引入了 SyncStream,它与 AsyncStream 共享相同的 API,但以同步方式运行。

以下是如何使用 SyncStream 的简单示例

let stream = SyncStream<Int> { continuation in
    for i in 0 ..< 10 {
        continuation.yield(i)
    }
    continuation.finish()
}

for value in stream {
    print(value, terminator: " ")
}
// 0 1 2 3 4 5 6 7 8 9

BidirectionalStream

受 Python 生成器的启发,它不仅可以使用 yield 生成值,还可以使用 send 接收值,并使用 return 引发 StopIteration 错误并停止流,Swift 中的 BidirectionalSyncStreamBidirectionalAsyncStream 分别为同步和异步操作提供了类似的功能。

有关 Python 生成器的更多信息,请参阅:PEP 255PEP 342文档

在以下示例中,流使用 send(_:) 方法将值发送回流,该值由 yield(_:) 返回值接收。

let stream = BidirectionalSyncStream<Int, Int, NoneType> { continuation in
    var value = 0
    while true {
        value = continuation.yield(value)
        value += 1
    }
}

try stream.next() // 0 start the stream
try stream.send(5) // 6 send value back to the stream, and get the next value

在以下示例中,当流的闭包使用 return(_:) 停止流式处理时,包含返回值的 StopIteration 错误将在闭包外部被捕获。

let stream = BidirectionalSyncStream<Int, Int, String> { continuation in
    var value = 0
    while true {
        value = continuation.yield(value)
        value += 1
        if value == 5 {
            continuation.return("Stop")
        }
    }
}

try stream.next() // 0 start the stream
do {
    try stream.send(4) // Throw StopIteration error
} catch {
    // get return value
    print((error as! StopIteration).value) // "Stop"
}

贡献

我们欢迎通过在 GitHub 上开启 pull request 来贡献 StreamUtilities。

许可证

StreamUtilities 在 Apache License 2.0 版本下发布。

版权所有 2024 Ruiyang Sun