Is it possible to satisfy Swift protocol and add defaulted arguments?

in Swift 3 you could use extensions to solve that, however it’s a bit ugly. Hope for a better solution in next swift versions.

import UIKit

protocol TestProtocol {
    func testFunction(a: Int, b: Int?) -> String
}

extension TestProtocol
{
    func testFunction(a: Int, b: Int? = nil) -> String {
        return testFunction(a: a, b: b)
    }
}

class TestClass: TestProtocol
{
    func testFunction(a: Int, b: Int?) -> String {
        return "a: \(a), b: \(b)"
    }
}

func testit(testProtocol: TestProtocol) {
    print(testProtocol.testFunction(a: 10)) // will print a: 10, b: nil
    print(testProtocol.testFunction(a:10, b:20)) // will print a: 10, b: Optional(20)
}

let t = TestClass()
testit(testProtocol: t)

However, this would somehow lead to one issue. If some class is not conforming to the protocol, it wont result in a compile error but rather in an endless loop.

A slightly better solution (in my opinion) is to capsulate the default parameter in a second function like this:

import Foundation

protocol TestProtocol {
    func testFunction(a: Int, b: Int?) -> String
}

extension TestProtocol
{
    // omit the second parameter here
    func testFunction(a: Int) -> String {
        return testFunction(a: a, b: nil) // <-- and use the default parameter here
    }
}

class TestClass: TestProtocol
{
   func testFunction(a: Int, b: Int?) -> String 
   {
       return "testFunction(a: \(a), b: \(b))"       
   }
}

func testit(testProtocol: TestProtocol) {
    print(testProtocol.testFunction(a: 10)) // will print a: 10, b: nil
    print(testProtocol.testFunction(a: 10, b: 20)) // will print a: 10, b: Optional(20)
}
print(Date())
let t = TestClass()
testit(testProtocol: t)

In this way the compiler will notify when a class does not conform to the protocol, and also wont end up in and endless loop.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)