0
0
Swiftprogramming~20 mins

Protocol extensions with default implementations in Swift - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Protocol Extension Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
Output of protocol extension default method call
What is the output of this Swift code when calling greet() on person?
Swift
protocol Greeter {
    func greet()
}

extension Greeter {
    func greet() {
        print("Hello from protocol extension")
    }
}

struct Person: Greeter {}

let person = Person()
person.greet()
AHello from protocol extension
BCompile-time error: Missing implementation of greet()
CRuntime error: Method greet() not found
DNo output
Attempts:
2 left
💡 Hint
Protocol extensions provide default implementations if the conforming type does not implement the method.
Predict Output
intermediate
2:00remaining
Overriding default implementation in protocol extension
What will be printed when greet() is called on dog?
Swift
protocol Greeter {
    func greet()
}

extension Greeter {
    func greet() {
        print("Hello from protocol extension")
    }
}

struct Dog: Greeter {
    func greet() {
        print("Woof! Hello from Dog")
    }
}

let dog = Dog()
dog.greet()
AHello from protocol extension
BCompile-time error: Duplicate method implementation
CWoof! Hello from Dog
DNo output
Attempts:
2 left
💡 Hint
If the conforming type implements the method, it overrides the default from the extension.
🔧 Debug
advanced
3:00remaining
Why does this code print the protocol extension method instead of the struct's method?
Given the code below, why does calling greeter.greet() print "Hello from protocol extension" instead of "Hi from Cat"?
Swift
protocol Greeter {
}

extension Greeter {
    func greet() {
        print("Hello from protocol extension")
    }
}

struct Cat: Greeter {
    func greet() {
        print("Hi from Cat")
    }
}

let cat = Cat()
let greeter: Greeter = cat
greeter.greet()
ABecause Cat does not implement greet(), the default method is called.
BBecause the method is called on a protocol-typed variable, the protocol extension method is used instead of the struct's method.
CBecause greet() is a static method, the protocol extension method is always called.
DBecause the protocol requires @objc, the method dispatch fails to call Cat's method.
Attempts:
2 left
💡 Hint
Consider how Swift dispatches methods when called on protocol-typed variables.
📝 Syntax
advanced
2:00remaining
Which option correctly adds a default implementation to a protocol method with parameters?
Given the protocol below, which option correctly provides a default implementation for describe(age:) in a protocol extension?
Swift
protocol Describable {
    func describe(age: Int)
}
A
extension Describable {
    func describe(age: Int) {
        print("Age is \(age)")
    }
}
B
extension Describable {
    func describe() {
        print("Age is unknown")
    }
}
C
extension Describable {
    func describe(age) {
        print("Age is \(age)")
    }
}
D
extension Describable {
    func describe(age: String) {
        print("Age is \(age)")
    }
}
Attempts:
2 left
💡 Hint
The method signature in the extension must exactly match the protocol's method signature.
🚀 Application
expert
3:00remaining
Using protocol extensions to add default behavior with constraints
Consider the protocol Summable below. Which option correctly uses a protocol extension with a constraint to provide a default implementation of sum() only for arrays of Int?
Swift
protocol Summable {
    associatedtype Element
    func sum() -> Element
}
A
extension Summable {
    func sum() -> Element {
        return 0
    }
}
B
extension Summable where Element == Int {
    func sum() -> Int {
        return self.reduce(0, +)
    }
}
C
extension Summable where Element: Numeric {
    func sum() -> Element {
        return (self as! [Element]).reduce(0, +)
    }
}
D
extension Summable where Element == Int {
    func sum() -> Int {
        return (self as! [Int]).reduce(0, +)
    }
}
Attempts:
2 left
💡 Hint
You must constrain the extension to Element == Int and cast self to [Int] to use reduce.