为什么改变 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.
以下代码在 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.