🎓 A1Learner
🔍
0 of 27 lessons completed

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?