是否可以对协议进行明确的一致性?

时间:2018-05-18 14:46:09

标签: swift protocols explicit-interface

  

首先要做的事情。因为我知道这是不可避免的,所以关于同一主题有一个similar question here。虽然话题是一样的,    其意图的推理/用法不同 。从而解决    问题与实现我在这里要求的内容不同。因此,请在将此标记为重复之前阅读我正在尝试解决的问题。谢谢!

在Swift中,我们使用与其他语言中的接口类似(但不完全相同)的协议。我在其他语言中看到的一件事,比如C#,是隐式和显式实现接口的能力。我想知道Swift是否具备后者的能力。

这是使用Swift语法显示的概念。注意这不会编译。这只是说明性的。

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

同样,上面是伪代码,但说明了其他语言如何支持此功能。

明确一致性的优点和好处

显式一致性的第一个优点是,您可以在不使自己的界面混乱的情况下符合协议。

例如,如果您有十个协议都定义了一个日期,它在功能上与您在模型中的日期匹配,但它们使用了十个不同的名称,显式一致性将允许您符合所有十个,而不具有在您的界面上公开展示这十个不同的名称。 (即上面,Invoice只会直接公开invoiceDate,即使它符合期望DateSortable的{​​{1}}。)

第二个优点是它可以保护您免受成员命名冲突的影响。

考虑两个不相关的协议,例如sortDateOrderable,但遗憾的是为其成员Deliverable选择了相同的名称,并且它们不归您所有。他们正处于你正在使用的框架中。

现在,在您自己的var date:Date{ get }模型中,您同时拥有PurchaseItemorderDate。明确的一致性会解决这个问题,就像这样......

deliveryDate

简而言之,显式接口声明允许您按功能关联事物,而不是盲目地按名称关联。如果你愿意的话,你仍然可以通过名字将它们联系起来,因为这是自动的,但这不再是一个要求。

那么,Swift有没有与上面类似的东西?

关闭,但不完全!

我能提出的最接近的事情是私有扩展,在需要的网站上添加对该协议的一致性,就像这样......

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

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

但是,这种方法存在局限性和警告,as seen here。当然,这个问题的需求是不同的,但警告仍然是一样的。

0 个答案:

没有答案