0

First things first. Since I know it's inevitable, there's a similar question here about this same topic. While the topic is the same, the reasoning/usage of it is different in its intent. Thus solving that question is not the same as achieving what I'm asking here. As such, please read what I'm trying to solve before marking this as a duplicate. Thanks!

In Swift, we use Protocols which are similar to (but not exactly the same as) Interfaces in other languages. One thing I've seen in those other languages, such as C#, is the ability to implement an interface both implicitly and explicitly. I'm wondering if Swift has the capability of the latter.

Here's the concept shown using Swift syntax. Note this will not compile. It's illustrative only.

protocol DateSortable{
    var sortDate:Date { get }
}

struct OrderedItem : DateSortable {

    // Implicit conformance because the name sortDate matches the protocol
    let sortDate:Date
}

struct Invoice : DateSortable {

    let invoiceDate:Date

    // Explicit conformance - Note you must specify the protocol name
    // Additionally, you cannot access 'invoice.sortDate' directly
    // You must cast to 'DateSortable' first
    var DateSortable.sortDate:Date { return invoiceDate }
}

let someDate      = orderedItem.sortDate                // Allowed
let someOtherDate = invoice.sortDate                    // *NOT* Allowed
let antherDate    = (invoice as! DateSortable).sortDate // Allowed

Again, the above is pseudo-code, but illustrates how other languages support this feature.

Advantages and Benefits of Explicit Conformance

The first advantage of explicit conformance is you can conform to a protocol without cluttering up your own interface.

For instance, if you have ten protocols that all define a date, which functionally matches a date you have in your model, but they use ten different names for it, explicit conformance would allow you to conform to all ten, without having to publicly expose those ten different names on your interface. (i.e. above, Invoice only exposes invoiceDate directly even though it conforms to DateSortable which expects sortDate.)

A second advantage is it protects you from member-naming collisions.

Consider two unrelated protocols, say Orderable and Deliverable that have unfortunately chosen the same name for their member, var date:Date{ get } and they aren't owned by you. They're in a framework you're using.

Now in your own PurchaseItem model, you have both orderDate and deliveryDate. Explicit conformance would address that, like so...

extension PurchaseItem : Orderable {
    var Orderable.date:Date { return orderDate }
}

extension PurchaseItem : Deliverable {
    var Deliverable.date:Date { return deliveryDate }
}

In short, explicit interface declarations let you relate things by functionality, not just blindly by name. You can still relate them by name if you want to, as that's automatic, but that's no longer a requirement.

So, does Swift have anything similar to the above?

Close, but not quite!

The closest thing I can come up with is a private extension adding conformance to that protocol at the site where it's needed, like so...

private extension Invoice : DateSortable {
    var DateSortable.sortDate:Date { return invoiceDate }
}

let someDate = invoice.sortDate // Only valid in the scope of this extension

However, there are limitations and caveats to this approach, as seen here. Granted, the need in that question is different, but the caveats remain the same.

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • 1
    Nope. But as with anything, there should be workarounds. – Sweeper May 18 '18 at 14:49
  • See my question: https://stackoverflow.com/questions/43743114/how-can-i-explicitly-implement-a-protocol-in-swift-if-it-is-impossible-why – Sweeper May 18 '18 at 14:54
  • I referenced your answer there, highlighting that there are caveats to that approach in that it's fragile (i.e. if someone changes the protocol as shown in your example, they can unintentionally hide your method implementation.) – Mark A. Donohoe May 18 '18 at 14:58
  • This is an interesting question, and I guess it's something you could suggest in the Swift Evolution forums, but is "avoid cluttering the object's interface" the only benefit? While I would appreciate it, I'm not sure it's a huge benefit. – EmilioPelaez May 18 '18 at 15:17
  • I updated the question showing the other benefit, which is the reverse of the first. The main takeaway is explicit conformance lets you relate things by functionality/intent, not just blindly by name (although you can implicitly still relate them by name if you choose.) That's the missing piece. – Mark A. Donohoe May 18 '18 at 15:31

0 Answers0