.count }.reduce(0, +) return Int(round(Double(size) / Double(count.toIntMax()))) } }

Agora podemos calcular o tamanho médio de qualquer coleção de filas (Array, Set, etc.). Sem extensões de protocolo, teríamos que adicionar este método a cada tipo de coleção separadamente.

Na biblioteca padrão do Swift, as extensões de protocolo são usadas para implementar, por exemplo, métodos como map, filter, reduce, etc.

a previsão de fluxos de caixa seria mais fácil para uma empresa em
extension Collection { public func map(_ transform: (Self.Iterator.Element) throws -> T) rethrows -> [T] { } }

Extensões de protocolo e polimorfismo

Como eu disse antes, as extensões de protocolo nos permitem adicionar implementações padrão de alguns métodos e também adicionar novas implementações de método. Mas qual é a diferença entre esses dois recursos? Vamos voltar ao gerenciador de erros e descobrir.

protocol ErrorHandler { func handle(error: Error) } extension ErrorHandler { func handle(error: Error) { print(error.localizedDescription) } } struct Handler: ErrorHandler { func handle(error: Error) { fatalError('Unexpected error occurred') } } enum ApplicationError: Error { case other } let handler: Handler = Handler() handler.handle(error: ApplicationError.other)

O resultado é um erro fatal.

Agora remova o handle(error: Error) declaração do método do protocolo.

protocol ErrorHandler { }

O resultado é o mesmo: um erro fatal.

Isso significa que não há diferença entre adicionar uma implementação padrão do método do protocolo e adicionar uma nova implementação do método ao protocolo?

Não! Existe uma diferença, e você pode vê-la alterando o tipo da variável handler de Handler para ErrorHandler.

let handler: ErrorHandler = Handler()

Agora, a saída para o console é: A operação não pôde ser concluída. (Erro de ApplicationError 0.)

Mas se retornarmos a declaração do método handle (error: Error) para o protocolo, o resultado mudará de volta para o erro fatal.

protocol ErrorHandler { func handle(error: Error) }

Vejamos a ordem do que acontece em cada caso.

Quando existe declaração de método no protocolo:

O protocolo declara o handle(error: Error) método e fornece uma implementação padrão. O método é sobrescrito no Handler implementação. Portanto, a implementação correta do método é invocada em tempo de execução, independentemente do tipo da variável.

Quando a declaração do método não existe no protocolo:

Como o método não é declarado no protocolo, o tipo não pode substituí-lo. É por isso que a implementação de um método chamado depende do tipo da variável.

Se a variável for do tipo Handler, a implementação do método do tipo é chamada. No caso da variável ser do tipo ErrorHandler, a implementação do método a partir da extensão do protocolo é chamada.

Código orientado a protocolo: seguro, porém expressivo

Neste artigo, demonstramos parte do poder das extensões de protocolo no Swift.

Ao contrário de outras linguagens de programação com interfaces, Swift não restringe protocolos com limitações desnecessárias. O Swift contorna peculiaridades comuns dessas linguagens de programação, permitindo que o desenvolvedor resolva a ambigüidade conforme necessário.

Com os protocolos e extensões de protocolo Swift, o código que você escreve pode ser tão expressivo quanto a maioria das linguagens de programação dinâmicas e ainda ter segurança de tipo no momento da compilação. Isso permite que você garanta a capacidade de reutilização e manutenção do seu código e faça alterações na base de código do aplicativo Swift com mais confiança.

Esperamos que este artigo seja útil para você e agradecemos qualquer feedback ou outras percepções.