Protocol conformance via extension in Swift - Time & Space Complexity
When a Swift type adopts a protocol through an extension, it gains new behavior. We want to understand how the time it takes to use that behavior changes as input grows.
How does the program's work grow when calling protocol methods added by extensions?
Analyze the time complexity of the following code snippet.
protocol Summable {
func sum() -> Int
}
extension Array: Summable where Element == Int {
func sum() -> Int {
var total = 0
for number in self {
total += number
}
return total
}
}
let numbers = [1, 2, 3, 4, 5]
let result = numbers.sum()
This code adds a sum() method to arrays of integers using a protocol extension. It calculates the total of all numbers in the array.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each element in the array to add it to a total.
- How many times: Once for every element in the array (n times, where n is the array size).
As the array gets bigger, the method does more additions, one per element.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 additions |
| 100 | 100 additions |
| 1000 | 1000 additions |
Pattern observation: The work grows directly with the number of elements. Double the elements, double the work.
Time Complexity: O(n)
This means the time to compute the sum grows linearly with the number of items in the array.
[X] Wrong: "Adding a method via protocol extension makes the code run instantly regardless of input size."
[OK] Correct: Even though the method is added by extension, it still processes each element one by one, so the time depends on input size.
Understanding how protocol extensions affect performance helps you explain your code choices clearly and shows you know how Swift handles behavior and efficiency together.
What if the sum() method used recursion instead of a loop? How would the time complexity change?
Practice
extension to conform a type to a protocol in Swift?Solution
Step 1: Understand protocol conformance
Protocols define a set of methods or properties a type must implement.Step 2: Role of extensions
Extensions allow adding these implementations to a type without changing its original code.Final Answer:
To add protocol requirements to a type without modifying its original definition -> Option AQuick Check:
Extensions add protocol conformance without altering original type [OK]
- Thinking extensions create subclasses
- Confusing extensions with method overriding
- Believing extensions declare new protocols
Car conform to protocol Drivable using an extension?Solution
Step 1: Identify correct extension syntax
Extensions use the format:extension TypeName: ProtocolName { ... }.Step 2: Check each option
extension Car: Drivable { func drive() { print("Driving") } } correctly extendsCarto conform toDrivableand implementsdrive().Final Answer:
extension Car: Drivable { func drive() { print("Driving") } } -> Option DQuick Check:
Correct extension syntax = extension Car: Drivable { func drive() { print("Driving") } } [OK]
- Placing extension inside struct
- Swapping type and protocol names
- Using 'protocol' keyword incorrectly
protocol Greetable {
func greet() -> String
}
struct Person {
let name: String
}
extension Person: Greetable {
func greet() -> String {
return "Hello, \(name)!"
}
}
let p = Person(name: "Anna")
print(p.greet())What is the output when this code runs?
Solution
Step 1: Check protocol conformance
Person is extended to conform to Greetable by implementing greet() returning "Hello, \(name)!".Step 2: Analyze output
Creating Person with name "Anna" and calling greet() returns "Hello, Anna!" which is printed.Final Answer:
"Hello, Anna!" -> Option CQuick Check:
Extension adds greet() returning personalized string [OK]
- Expecting error due to missing conformance
- Ignoring string interpolation
- Assuming default greet() implementation
Rectangle conform to Shape via extension, but it causes a compile error. What is the error?protocol Shape {
var area: Double { get }
}
struct Rectangle {
var width: Double
var height: Double
}
extension Rectangle: Shape {
func area() -> Double {
return width * height
}
}Solution
Step 1: Check protocol requirement
Shape requires a propertyareaof typeDoublewith a getter.Step 2: Analyze extension implementation
The extension implementsarea()as a method, but protocol expects a computed propertyvar area: Double { get }.Final Answer:
Method 'area()' should be a computed property, not a function -> Option AQuick Check:
Property requirement needs computed property, not method [OK]
- Implementing property as method
- Thinking structs can't conform via extension
- Ignoring protocol property vs method difference
Printable requiring a method printDetails(). You want to add this conformance to an existing class Book without changing its original code. Which approach correctly achieves this and allows printDetails() to print the book's title and author?class Book {
let title: String
let author: String
init(title: String, author: String) {
self.title = title
self.author = author
}
}Solution
Step 1: Understand requirement
We want to add Printable conformance to Book without changing Book's original code.Step 2: Use extension to conform
extension Book: Printable { func printDetails() { print("Title: \(title), Author: \(author)") } } extends Book to conform to Printable and implements printDetails() accessing Book's properties.Final Answer:
extension Book: Printable { func printDetails() { print("Title: \(title), Author: \(author)") } } -> Option BQuick Check:
Extension adds protocol conformance and method using existing properties [OK]
- Trying to modify original class code
- Incorrectly extending protocol instead of class
- Not implementing required method
Ready to prove it?
Pass the test and this pattern moves unknown
