При реализации метода протокола в расширении нужно ли указывать метод в протоколе?

Мне нравится, как Swift позволяет вам определить метод в протоколе, а затем через расширение этого протокола реализовать этот метод. Однако, особенно в случаях, когда вы определяете протокол и расширение в одной области действия и с одинаковыми уровнями доступа, нужно ли вам в первую очередь определять метод в протоколе?

Рассмотрим этот код:

public protocol MyProtocol {
    func addThese(a:Int, b:Int) -> Int
}

public extension MyProtocol {
    func addThese(a:Int, b:Int) -> Int{
        return a + b
    }
}

Чем это отличается от этого?

public protocol MyProtocol {
}

public extension MyProtocol {
    func addThese(a:Int, b:Int) -> Int{
        return a + b
    }
}

Примечание. Я специально спрашиваю о протоколе и расширении, определяемых вместе в одной области с одинаковыми уровнями доступа.

Если бы это было не так, т.е. расширение находится в другой области действия, чем протокол, — тогда, очевидно, только элементы в той же области, что и расширение, получат автоматическую реализацию. Это имеет смысл.

т. е. в модуле А:

public protocol MyProtocol {
    func addThese(a:Int, b:Int) -> Int
}

В модуле Б

internal extension MyProtocol {
    func addThese(a:Int, b:Int) -> Int{
        return a + b
    }
}

Все элементы в модуле B, которые реализуют MyProtocol, автоматически получат реализацию для addThese, тогда как элементы, которые реализуют MyProtocol в другой области, по-прежнему должны явно удовлетворять протоколу.

Опять же, речь идет о совместном определении протокола и расширения. Нужно ли определять функцию в самом протоколе, или это просто считается хорошей практикой?


person Mark A. Donohoe    schedule 10.01.2018    source источник
comment
Черт, это удалило комментарий Мартина:/ Вот сообщение в блоге, на которое он ссылался: oleb.net/blog/2016/06/kevin-ballard-swift-dispatch   -  person Hamish    schedule 10.01.2018


Ответы (1)


Вам не нужно определять метод в протоколе, вы можете добавлять методы в протоколы, используя расширения, как вы сказали, я делал это много раз. Я вижу в этом удобный способ передать часть наследства классам, которые уже соответствовали протоколу.

На самом деле вы даже можете расширить собственные протоколы, такие как UITableViewDataSource или UITableViewDelegate. Например, вы можете захотеть, чтобы все ваши контроллеры представлений, обрабатывающие табличное представление, имели доступ к одному удобному методу.

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

Если вы все еще сомневаетесь, вы можете прочитать документацию: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Extensions.html

Расширения добавляют новые функции к существующему классу, структуре, перечислению или типу протокола.

Так что я не считаю это плохой практикой, вы просто добавляете новую функциональность.

person Oscar A. Esquivel Oviedo    schedule 10.01.2018