Swift Actors
An actor protects its stored data by running access to that data one piece at a time. Code outside an actor reaches its stored data and methods through await.
A counter actor
The Counter actor stores one number and changes it through its methods. Each outside call carries await, and the final read prints 8.
actor Counter {
var value = 0
func add(amount: Int) {
value += amount
}
func read() -> Int {
value
}
}
let counter = Counter()
await counter.add(amount: 5)
await counter.add(amount: 3)
let total = await counter.read()
print(total)Named scores inside an actor
The ScoreBoard actor stores one score per name in a dictionary. Two awaited record calls fill the board before two awaited reads print the scores.
actor ScoreBoard {
var scores: [String: Int] = [:]
func record(name: String, points: Int) {
scores[name] = points
}
func points(for name: String) -> Int {
scores[name] ?? 0
}
}
let board = ScoreBoard()
await board.record(name: "Ana", points: 12)
await board.record(name: "Ben", points: 9)
let ana = await board.points(for: "Ana")
let ben = await board.points(for: "Ben")
print(ana)
print(ben)A call missing await
The read call in this program carries no await. The compiler rejects the program, and the stated output shows the first error line.
actor Counter {
var value = 0
func read() -> Int {
value
}
}
let counter = Counter()
print(counter.read())Example
actor Vault {
var balance = 0
func deposit(amount: Int) {
balance += amount
}
func withdraw(amount: Int) {
balance -= amount
}
func balanceNow() -> Int {
balance
}
}
let vault = Vault()
await vault.deposit(amount: 50)
await vault.withdraw(amount: 20)
let left = await vault.balanceNow()
print(left)Key points
- The actor keyword defines a type with isolated stored data.
- A method call on an actor from outside carries await.
- The await marks a point where the program may pause while the actor becomes free.
- Calls made inside an actor method need no await for that same actor.
- A missing await on an outside call is a compile error.
In this example, the Vault actor starts with a balance of zero. A deposit of 50 and a withdrawal of 20 run through awaited calls. The final awaited read prints 30.
Note
Awaited calls written in sequence run in their written order.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What marks a call to an actor method from outside the actor?