Protocols Are Confusing Me

90 views
Skip to first unread message

Thomas Wetmore

unread,
Jul 24, 2014, 12:11:18 AM7/24/14
to swift-l...@googlegroups.com
I have a protocol issue that is confusing me. With these protocols:

protocol Event
{  func dateq () -> Date? }

protocol Date
{   func yearq () -> Int? }

and these classes:

class GedcomEvent: Event
{
    init () { ... }
    func dateq() -> GedcomDate?  // Error: Protocol requires function 'dateq()' with type '() -> Date?'
    { ... }
}

class GedcomDate: Date
{
init () { ... }
    func yearq () -> Int? { return nil }
}

I get the compiler error shown above. If I replace 'GedcomDate?' in the offending line with 'Date?' the compiler is happy. 

Is this expected behavior? It doesn't seem right to me. Yes, a GedcomDate must meet the Date protocol, but within the specific GedcomEvent class I also want to use specific properties of the GedcomDate class that are not reflected in the Date protocol. Isn't it the case with the real dateq() method having to return a Date? instead of a GedcomDate? that I am loosing the details of the full GedcomDate class?

Tom Wetmore

Derrick Hathaway

unread,
Jul 24, 2014, 12:54:25 AM7/24/14
to swift-l...@googlegroups.com, Thomas Wetmore

Is this expected behavior? It doesn't seem right to me. Yes, a GedcomDate must meet the Date protocol, but within the specific GedcomEvent class I also want to use specific properties of the GedcomDate class that are not reflected in the Date protocol. Isn't it the case with the real dateq() method having to return a Date? instead of a GedcomDate? that I am loosing the details of the full GedcomDate class?

Hi Tom,
What you’re looking for is called covariant return types. Most object-oriented languages have support for this including Objective-C. Swift doesn’t yet have support. I would bet that this will be supported eventually. The previous post is somewhat related and links to an interesting article about that types of type variance that Swift currently supports:


In the short term you will have to downcast Date to GedcomDate in cases where you have enough type info to do so:

let event = GedcomEvent()

    // sometime later
    if let gedcomDate = event.dateq() as? GedcomDate {
        // do something with gedcomDate which now has the type GedcomDate
    }

hopefully covariant return types will be supported eventually.

Cheers,
Derrick
Reply all
Reply to author
Forward
0 new messages