StreamUtilities
是一个工具箱,为 Swift 中的流操作提供两个实用工具
SyncStream
:一个类,用于生成一系列值,灵感来源于 Swift 标准库中的 AsyncStream
,但以同步方式运行。BidirectionalStream
:旨在为 Swift 带来类似于 Python 生成器的功能。用户可以使用 yield
生成值,使用 send
发送值,并通过抛出 StopIteration
错误来关闭流。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
受 Python 生成器的启发,它不仅可以使用 yield
生成值,还可以使用 send
接收值,并使用 return
引发 StopIteration
错误并停止流,Swift 中的 BidirectionalSyncStream
和 BidirectionalAsyncStream
分别为同步和异步操作提供了类似的功能。
有关 Python 生成器的更多信息,请参阅:PEP 255,PEP 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