Reputation: 628
In using protocol extension for default implementation I encounter a problem. I define a protocol with different optional properties and functions to use. In the extension I implement a default function and nil properties. In the implementation I use properties and functions from within the protocol.
On the device it works how I expect. Also on the debugger it gave me the property from the class when I run into breakpoint within the extension implementation.
Can someone help me out why I didn't get the property in the example from the class but the nil property from extension.
Example from playground
import UIKit
protocol Collectable {
var item: String? { get }
func collect()
}
extension Collectable {
var item: String? { return nil }
func collect() {
if let some = item {
print("collect \(some)")
} else {
print("nothing")
}
}
}
class Car: Collectable {
var item = "letter"
}
let car = Car()
car.collect()
Upvotes: 2
Views: 266
Reputation: 114826
As @SavcaMarin stated in their answer, you have a type conflict between the item
property declared in your extension (String?
) and the one in your Car
(String
).
You can see this if you comment the extension. The compiler will tell you that Car
does not conform to Collectable
. If you ask it to create the required stubs it will create func collect
and var item: String?
. It then gives an error that item
is re-defined.
As Rob and Matt pointed out in comments on the other answer, this seems to be a bug in the Swift compiler. It doesn't indicate the re-definition of item
or the non-conformance of your item
to the protocol if there is a default implementation that satisfies the protocol conformance (your extension).
The simple fix is to tell Swift that the item
in Car
is the same as item in Collectable
by declaring the type explicitly (String?
) rather than relying on type inference (Which gives String
):
class Car: Collectable {
var item:String? = "letter"
}
Upvotes: 1
Reputation: 437
In the protocol your item is optional string, while in your class you declared another variable named also item. Your collect function is looking for the optional item, and in the extension you specified that it should return nil.
Upvotes: 2