The following code is legal in Swift 5.5 (beta):
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"
}
Why is this legal? The dog property is shared state, isn't it? Aren't we in danger of accessing the actor's dog on different threads simultaneously? Isn't that what actors are supposed to protect us from?
Curiously, if the actor's dog
property were declared with var
instead of let
, we'd be compelled to say await
during access. Why does that make a difference? Dog is a reference type; it is mutable in place, and it is mutable in exactly the same way regardless of whether it is declared with let
or var
.
dog
declaration isvar
we are forced to useawait
for access, but if thedog
declaration islet
, we are not. A constant reference to a nonSendable reference type is not more thread-safe than avar
reference! – Lisabeth