Protocol extensions with default implementations in Swift - Time & Space Complexity
We want to understand how the time it takes to run code changes when using protocol extensions with default implementations in Swift.
Specifically, we ask: How does adding default methods in protocol extensions affect the speed as the program runs?
Analyze the time complexity of the following code snippet.
protocol Greetable {
func greet()
}
extension Greetable {
func greet() {
print("Hello from default implementation")
}
}
struct Person: Greetable {}
let n = 10
let people = Array(repeating: Person(), count: n)
for person in people {
person.greet()
}
This code defines a protocol with a default greet method, creates many Person instances, and calls greet on each.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Calling the
greet()method on eachPersoninstance. - How many times: Exactly once for each element in the
peoplearray, which hasnelements.
As the number of people grows, the number of greet calls grows the same way.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 greet calls |
| 100 | 100 greet calls |
| 1000 | 1000 greet calls |
Pattern observation: The work grows directly with the number of items. Double the items, double the calls.
Time Complexity: O(n)
This means the time to run grows in a straight line with the number of elements we process.
[X] Wrong: "Using protocol extensions with default methods makes the code slower because it adds extra layers."
[OK] Correct: The default method is called just like any other method, so the time to run depends mainly on how many times you call it, not on it being a default implementation.
Understanding how default methods in protocols affect performance helps you write clean, reusable code without worrying about hidden slowdowns.
"What if the greet method was overridden in Person with a more complex operation? How would the time complexity change?"
Practice
protocol extensions with default implementations in Swift?Solution
Step 1: Understand protocol extensions
Protocol extensions allow adding methods or properties with default behavior to protocols.Step 2: Identify the purpose of default implementations
Default implementations let conforming types use common code without writing it themselves.Final Answer:
To provide default method implementations that all conforming types can use -> Option DQuick Check:
Default implementations = shared code for all [OK]
- Thinking protocols can store properties
- Confusing protocol inheritance with extensions
- Believing all methods must be implemented manually
Solution
Step 1: Recall syntax for protocol extensions
Default implementations are added inside anextensionof the protocol.Step 2: Check each option
extension MyProtocol { func greet() { print(\"Hello\") } } correctly usesextension MyProtocol { func greet() { ... } }. Others misuse keywords or structure.Final Answer:
extension MyProtocol { func greet() { print("Hello") } } -> Option AQuick Check:
Useextensionto add defaults [OK]
- Trying to put method bodies inside protocol declaration
- Using 'extension' inside protocol block
- Omitting the 'extension' keyword
protocol Speaker {
func speak()
}
extension Speaker {
func speak() {
print("Speaking from extension")
}
}
struct Person: Speaker {
func speak() {
print("Person speaking")
}
}
struct Robot: Speaker {}
let p = Person()
p.speak()
let r = Robot()
r.speak()What is the output when this code runs?
Solution
Step 1: Understand method resolution for protocol extensions
If a conforming type provides its own method, it overrides the default from the extension.Step 2: Analyze the structs
Person implementsspeak()so it prints "Person speaking". Robot does not implement it, so uses default "Speaking from extension".Final Answer:
Person speaking Speaking from extension -> Option CQuick Check:
Own method overrides default extension [OK]
- Assuming default is always called
- Expecting Robot to cause error
- Confusing protocol declaration with implementation
describe() in a protocol extension, but it causes a compile error. What is the mistake?protocol Describable {
func describe()
}
extension Describable {
func describe
{
print("Default description")
}
}Solution
Step 1: Check method syntax in extension
Method definitions require parentheses even if no parameters are present.Step 2: Identify the error
The extension methodfunc describeis missing parentheses()after the name.Final Answer:
Missing parentheses after method name in extension -> Option BQuick Check:
Method syntax needs () even if empty [OK]
- Omitting parentheses in method declaration
- Thinking protocol methods must have bodies
- Believing extensions can't implement methods
Identifiable with a property id and a default method identify() that prints the id. How would you write the protocol and extension so that conforming types can use the default identify() without extra code?Solution
Step 1: Define protocol with read-only property
Usevar id: String { get }to require an id property that conforming types must provide.Step 2: Provide default identify() method in extension
Extension addsidentify()that prints the id using string interpolation.Final Answer:
protocol Identifiable { var id: String { get } }\nextension Identifiable { func identify() { print("ID: \(id)") } } -> Option AQuick Check:
Protocol requires id; extension adds identify() [OK]
- Using var id: String without { get } or { get set }
- Trying to provide stored properties in protocol extension
- Defining identify() in protocol but not implementing in extension
Ready to prove it?
Pass the test and this pattern moves unknown
