为什么改变 actor 的 nonSendable 属性 是合法的?

why is it legal to mutate an actor's nonSendable property?

以下代码在 Swift 5.5(测试版)中是合法的:

class Dog {
    var name = "rover"
    var friend : Dog? = nil
}
actor MyActor {
    let dog = Dog()
}
func test() async {
    let act = MyActor()
    act.dog.name = "fido"
    act.dog.friend = Dog()
    act.dog.friend?.name = "fido"
}

为什么这是合法的?狗 属性 是共享状态,不是吗?我们不是有同时在不同线程上访问演员的狗的危险吗?这不是演员应该保护我们免受的伤害吗?

奇怪的是,如果演员的 dog 属性 是用 var 而不是 let 声明的,我们将不得不在访问期间说 await .为什么会有所不同? Dog 是引用类型;它是就地可变的,并且无论它是用 let 还是 var.

声明的,它都以完全相同的方式可变

你是对的,这种访问是不安全的,Swift 今天的 5.5 不会阻止这种情况,除非你明确地传递 -warn-concurrency 标志。

请参阅Staging in Sendable checking proposal (and forums post讨论检查功能的推出计划)。

您还可以在此处的路线图更新中阅读 Swift 5.5 和 Swift 6 之间关于并发安全的总体计划:Concurrency in Swift 5 and 6.