Access control and protected mutation
Access control and protected mutation
A register should allow readers to see its attendance count while keeping changes behind an intentional method. Access control states where declarations may be used. It helps maintain an API contract rather than relying on every caller to avoid changing internal fields.
What you’ll learn
- Expose readable state while restricting its setter.
- Place validation in controlled state-changing operations.
Access control and protected mutation in the example
Readable state
A register should allow readers to see its attendance count while keeping changes behind an intentional method.
Readable stateControlled operation
Swift defaults to internal access within a module.
Controlled operationRestricted setter
The method intentionally increments count to one.
Restricted setter
How access control and protected mutation works
Swift defaults to internal access within a module. Private and fileprivate restrict implementation visibility; public exposes appropriate API across modules, while open also permits relevant subclassing and overriding outside the defining module. A private(set) property can be readable more widely while keeping its setter private.
Work through access control and protected mutation
Save this complete program as main.swift and run it with the Swift toolchain. No separate input file is needed.
Swift · complete program
struct Register {
private(set) var count = 0
mutating func recordArrival() { count += 1 }
}
var register = Register()
register.recordArrival()
print(register.count)Expected output
1Follow the execution
The method intentionally increments count to one. External code in this example can read count, but cannot directly assign register.count = 50 because the setter is private. Mutating is required because Register is a struct.
Try this program in the Swift compiler. Paste the complete source above.
Practice: Access control and protected mutation
Your task: Where should you add validation if arrivals have a maximum count?
Swift · complete program
struct Register {
private(set) var count = 0
mutating func recordArrival() { count += 1 }
}
var register = Register()
register.recordArrival()
print(register.count)Worked answer
Put it in the operation that changes count, and define a result for reaching the limit. A restricted setter makes that centralized policy harder to bypass through ordinary callers.
Centralize the permitted updates
Access control is a source-level API rule, not encryption or a protection against someone controlling the running process. Package access also exists for declarations shared within a Swift package; choose boundaries appropriate to the project structure.
Check your decision
Centralize the permitted updates
Put it in the operation that changes count, and define a result for reaching the limit. A restricted setter makes that centralized policy harder to bypass through ordinary callers. Access control is a source-level API rule, not encryption or a protection against someone controlling the running process.
Further reading: official Swift language guide.
Reaching the recap and completing the quizzes are separate milestones.