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.