我有一个Actor
对象,我希望它能够迭代和过滤。
actor DataModel {
typealias Details = (passed: Bool, scores: [Int])
private(set) var data: [Int: Details] = [:]
func update(_ value: (Bool, [Int]), forKey key: Int) {
data.updateValue(value, forKey: key)
}
subscript(id: Int) -> Details? {
get {
data[id]
}
set {
data[id] = newValue
}
}
func removeAll() {
data.removeAll()
}
}
extension DataModel: AsyncSequence, AsyncIteratorProtocol {
typealias Element = (key: Int, value: Details)
func next() async throws -> Element? {
var iterator = data.makeIterator()
return iterator.next()
}
nonisolated func makeAsyncIterator() -> Data {
self
}
}
let data = DataModel()
await data.update((false, [1, 2]), forKey: 0)
但是,每当我使用filter
方法时,它就会进入无限循环。
let filtered = data.filter { el in
/// infinite loop
return el.value.passed || el.value.scores.count > 3
}
for try await i in filtered {
print(i)
}
- 更新**
创建了单独的迭代器,但出现以下错误:
不能从非隔离上下文引用参与者隔离属性"data
extension DataDetail: AsyncSequence {
typealias Element = (key: Int, value: (passed: Bool, scores: [Int]))
typealias AsyncIterator = DataInterator
nonisolated func makeAsyncIterator() -> DataInterator {
return DataInterator(data) /// Actor-isolated property 'data' can not be referenced from a non-isolated context
}
}
struct DataInterator: AsyncIteratorProtocol {
typealias Detail = (key: Int, value: (passed: Bool, scores: [Int]))
private let details: [Int: (passed: Bool, scores: [Int])]
lazy var iterator = details.makeIterator()
init(_ details: [Int: (passed: Bool, scores: [Int])]) {
self.details = details
}
mutating func next() async throws -> Detail? {
let nextDetail = iterator.next()
return nextDetail
}
}
1条答案
按热度按时间afdcj2ne1#
你的
next()
方法有一个错误,你在每次调用时都创建了一个新的迭代器,所以每次对next()
方法的调用实际上都是一遍又一遍地返回data.first
,它永远不会命中nil
,所以它永远不会结束。但是我不知道最简单的解决方法是什么,你不能从
makeAsyncIterator()
中直接得到return data.makeIterator()
,因为data
是角色隔离的。您可能希望创建一个新的符合
AsyncIteratorProtocol
的结构体,该结构体 Package 您的actor并以actor隔离的方式出售其data
的元素