Understanding Swift default valued properties inside a Protocol extension

Viewed 314

I have this sample protocol having a default valued property with extension.

protocol SampleProtocol{
    var sample:String?{get set}
}
extension SampleProtocol{
    var sample:String?{ get { return nil } set{} }
}

Now, my TestClass implements SampleProtocol as below.

class TestClass:SampleProtocol {
    var sample: String?{
        return "TestClass"
    }
}

And there's one helper method that prints a sample value from the SampleProtocol.

func printValue(_ value: SampleProtocol){
    print(value.sample)
}

Now the problem is

let testObj = TestClass()
print(testObj.sample) // prints "TestClass"
printValue(testObj) // prints nil

From the above result, I need to understand why when the testObj is typecasted into SampleProtcol, it is considering default implementation from extension instead of the implementation from the TestClass?

1 Answers

The problem is that the TestClass is not implementing the SampleProtocol so when you pass it in the printValue method that takes a SampleProtocol, it will call the default implementation in the protocol extension(since the instance you pass does not implement the protocol method).

In the SampleProtocol you have defined the variable as {get set} but in the TestClass variable you have only provided a getter, this does not match the requirements (If you remove the protocol extension you will see an error that the class does not conform to the protocol).

It will work if you provide a setter:

class TestClass: SampleProtocol {
    var sample: String? {
        get {
        return "TestClass"
        } set { }
    }
}
Related