Возможно ли иметь только явное соответствие протоколу? - PullRequest
0 голосов
/ 18 мая 2018

Перво-наперво.Поскольку я знаю, что это неизбежно, здесь есть похожий вопрос по этой же теме.Хотя тема та же самая, обоснование / использование ее отличается по своему намерению.Таким образом, решение этого вопроса - не то же самое, что достижение того, что я здесь задаю.Поэтому, пожалуйста, прочитайте то, что я пытаюсь решить, прежде чем пометить это как дубликат.Спасибо!

В 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, что предполагает sortDate.)

Второе преимущество заключается в том, что он защищает вас от конфликтов имен членов.

Рассмотрим два несвязанных протокола, скажем Orderable и Deliverable, которые, к сожалению, выбрали одно и то же имя для своего члена, var date:Date{ get }, и они не принадлежат вам.Они находятся в используемой вами среде.

Теперь в вашей собственной PurchaseItem модели у вас есть и orderDate и deliveryDate.Явное соответствие могло бы решить эту проблему, например, так ...

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

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

Короче говоря, явные объявления интерфейса позволяют связывать вещи по функциональности, а не только по имени.Вы все равно можете связать их по имени, если хотите, поскольку это автоматически, но это больше не является обязательным требованием.

Итак, есть ли у Swift что-то похожее на приведенное выше?

Закрыть, но не совсем!

Самое близкое, что я могу придумать, - это частное расширение, добавляющее соответствие этому протоколу на сайте, где он необходим, например ...

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

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

Однако у этого подхода есть ограничения и предостережения , как видно здесь .Конечно, потребность в этом вопросе иная, но предостережения остаются прежними.

...