Skip to content

Instantly share code, notes, and snippets.

@RoyalIcing
Last active March 31, 2021 00:38
Show Gist options
  • Save RoyalIcing/b2af1072b3475a5eb2dd7d3051a70830 to your computer and use it in GitHub Desktop.
Save RoyalIcing/b2af1072b3475a5eb2dd7d3051a70830 to your computer and use it in GitHub Desktop.
Defining Actors in Swift with Protocols
protocol Actor : AnyObject, Sendable {
associatedtype State
isolated var state: State
}
struct BankAccountState {
var balance: Double
mutating func deposit(amount: Double) {
assert(amount >= 0)
balance = balance + amount
}
mutating func withdraw(amount: Double) throws {
assert(amount >= 0)
if amount > state.balance {
throw BankError.insufficientFunds
}
balance = balance - amount
}
}
class BankAccount : Actor {
let accountNumber: Int
var state: BankAccountState
init(accountNumber: Int, initialDeposit: Double) {
self.accountNumber = accountNumber
self.state = BankAccountState(balance: initialDeposit)
}
async var balance: Double { await state.balance }
mutating func transfer(amount: Double, to other: BankAccount) async throws {
// Safe: this operation is the only one that has access to the actor's isolated
// state right now, and there have not been any suspension points between
// the place where we checked for sufficient funds and here.
try state.withdraw(amount: amount)
print("Transferring \(amount) from \(accountNumber) to \(other.accountNumber)")
// Safe: the deposit operation is placed in the `other` actor's mailbox; when
// that actor retrieves the operation from its mailbox to execute it, the
// other account's balance will get updated.
await other.deposit(amount: amount)
}
mutating func deposit(amount: Double) {
state.deposit(amount: amount)
}
}
var bankAccountA = BankAccount(accountNumber: 7, initialDeposit: 200)
var bankAccountB = BankAccount(accountNumber: 42, initialDeposit: 200)
await bankAccountA.deposit(amount: 200)
await bankAccountA.transfer(amount: 100, to: bankAccountB)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment