如何从过滤器闭包中访问actor



我不知道如何从过滤器闭包访问演员。看下面的示例代码:

import Foundation
actor MyActor {
var contents: [String]

init() {
self.contents = []
}
}

let myActor = MyActor()
let list: [String] = []
Task {
list.filter { item in myActor.contents.contains { $0 == item } }
}

得到语法错误:Actor-isolated property 'contents' can not be referenced from a non-isolated context。这是有道理的,但我就是不知道如何提供正确的语法。

先将演员的内容放入let的局部常量中,然后在filter中使用该局部常量:

Task {
let actorContents = await myActor.contents
let result = list.filter { item in actorContents.contains { $0 == item } }
}

如果myActor.contents在过滤过程中的某个时刻发生变化,您不会希望filter在中途使用更新的myActor.contents,对吗?因此,先在本地创建一个副本,然后再使用。

另外,考虑使用Set以获得更好的效率:

let actorContents = Set(await myActor.contents)
let result = list.filter { item in actorContents.contains(item) }

另一种方法是将过滤例程移动到参与者中:

actor MyActor {
var contents: Set<String> = []
func filtering(_ items: [String]) -> [String] {
items.filter { contents.contains($0) }
}
}

那么,这就简化了调用点:

func foo() {
Task {
let filtered = await myActor.filtering(list)
}
}

这将同步逻辑移动到参与者(IMHO,它所属的位置)。

最新更新