Protocol em Swift — o que é, sintaxe e possibilidades

Autor: IT Sectr Publicado: 2026-06-17 Tempo de leitura: 6 min

Protocol em Swift é um contrato que define um conjunto de requisitos que qualquer tipo adotante deve satisfazer. Os protocolos são a base da Programação Orientada a Protocolos (POP) — um paradigma recomendado pela Apple para Swift juntamente com a POO clássica. De acordo com a Apple Documentation, 2026, estruturas, classes e enums podem adotar protocolos, tornando a arquitetura flexível e testável.

Principais pontos

  • Protocol — um contrato com requisitos para estruturas, classes e enums
  • Requisitos incluem métodos, propriedades, inicializadores e subscritos
  • Protocol Composition permite combinar vários protocolos
  • POP — Programação Orientada a Protocolos, alternativa à herança
  • Protocol Extensions adicionam implementações padrão para métodos

O que é Protocol em Swift?

Protocol é uma interface abstrata que define o que um tipo deve ser capaz de fazer, mas não como ele faz. Em Swift, um protocolo é análogo às interfaces em Java ou Go, mas com capacidades adicionais.

Um protocolo pode exigir:

  • Métodos de instância e de tipo (estáticos)
  • Propriedades com especificadores { get } ou { get set }
  • Inicializadores
  • Subscritos
  • Tipos associados (genéricos a nível de protocolo)

De acordo com a WWDC 2015, a Apple introduziu a Programação Orientada a Protocolos como uma abordagem fundamental para a arquitetura de aplicações Swift. Ao contrário da POO, onde a herança de classes cria hierarquias rígidas, a POP oferece composição de protocolos. Isto proporciona flexibilidade: um único tipo pode estar em conformidade com vários protocolos, obtendo seus requisitos e implementações através de extensões.

Sintaxe de declaração de protocolos

Protocol é declarado com a palavra-chave protocol, um nome e um corpo.

swift
protocol Drawable {
    func draw(context: CGContext)
    var boundingBox: CGRect { get }
}

Um tipo adota um protocolo usando dois pontos após seu nome:

swift
struct Circle: Drawable {
    let center: CGPoint
    let radius: CGFloat

    func draw(context: CGContext) {
        context.addArc(center: center, radius: radius, ...)
    }

    var boundingBox: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
}

Um único tipo pode adotar vários protocolos separados por vírgulas: struct MyType: ProtocolA, ProtocolB. O compilador verifica se todos os requisitos de cada protocolo foram cumpridos.

Requisitos de propriedades e métodos

Requisitos de propriedades são declarados com a palavra-chave var e os especificadores de acesso { get } ou { get set }.

swift
protocol UserProtocol {
    var name: String { get }
    var age: Int { get set }
    static var maxAge: Int { get }
    mutating func updateName(_ newName: String)
}

A palavra-chave mutating em um protocolo indica que o método pode modificar self. As estruturas devem implementar tal método como mutating, enquanto as classes podem omiti-lo. Requisitos de métodos são declarados com uma assinatura completa, incluindo rótulos de parâmetros.

Herança de protocolos

Protocol pode herdar de outro protocolo, adicionando novos requisitos. Isto cria uma hierarquia de contratos sem acoplamento rígido a classes.

swift
protocol Vehicle {
    var speed: Double { get set }
    func move()
}

protocol Flyable: Vehicle {
    var altitude: Double { get set }
    func takeOff()
}

Um tipo que adota Flyable deve cumprir os requisitos de ambos os protocolos — Vehicle e Flyable. Swift suporta herança múltipla de protocolos: protocol A: B, C.

Protocol Composition

Protocol Composition é um mecanismo que permite especificar que um tipo deve estar em conformidade com vários protocolos simultaneamente, sem criar um novo protocolo combinado.

swift
func render(_ item: Drawable & Animatable) {
    item.draw(context: ...)
    item.animate(duration: 0.3)
}

A composição (&) funciona em parâmetros de funções, variáveis e restrições genéricas. O compilador verifica que o tipo passado simultaneamente satisfaz todos os protocolos. A composição é amplamente usada em SwiftUI: some View é um genérico com composição.

Protocol Composition é preferível a criar uma hierarquia de herança: em vez de protocol A: B, C, pode-se adotar B & C diretamente. Isto proporciona flexibilidade e reduz o acoplamento. A composição é especialmente útil em parâmetros de funções e restrições genéricas onde é necessário combinar temporariamente requisitos sem criar um protocolo intermediário. Isto reduz o número de tipos auxiliares no código.

Protocolo como tipo

Protocol pode ser usado como tipo de uma variável, parâmetro de função ou elemento de coleção. Isto é chamado de tipo existencial.

swift
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]

func process(drawables: [any Drawable]) {
    for item in drawables {
        item.draw(context: ...)
    }
}

A palavra-chave any (Swift 5.6+) marca explicitamente um existencial. Sem any, o compilador emite um aviso. Swift também suporta some (tipos opacos) para ocultar o tipo concreto atrás de um protocolo — esta é uma abordagem padrão em SwiftUI.

Erros comuns com protocolos

Ao trabalhar com protocolos, os desenvolvedores frequentemente cometem vários erros recorrentes.

  • Mutating esquecido — um método está marcado como mutating no protocolo, mas uma estrutura o implementa sem a palavra-chave
  • Protocolo como tipo em vez de genérico — usar Drawable em vez de <T: Drawable> onde um tipo concreto é necessário
  • Referência circular de protocolo — um protocolo que referencia a si mesmo através de um tipo associado sem resolução adequada
  • Protocolo apenas para classes — usar AnyObject desnecessariamente, o que exclui struct e enum

Perguntas frequentes

Qual a diferença entre protocol e abstract class?

Protocol define apenas requisitos sem implementação (até o surgimento de protocol extensions). Uma abstract class pode conter implementação e estado. Swift não tem classes abstratas — seu papel é desempenhado por protocolos com extensões.

Pode uma struct adotar um protocol?

Sim, estruturas, classes e enums podem todos adotar protocolos. Esta é a base da POP: você não precisa usar classes para organizar a arquitetura. Estruturas com protocolos fornecem semântica de valor e imutabilidade.

O que é um tipo associado em um protocolo?

Tipo associado (associatedtype) é um marcador de posição para um tipo que o tipo implementador determina por si mesmo. Exemplo: Collection tem associatedtype Element. É um genérico a nível de protocolo.

Posso restringir um protocolo apenas para classes?

Sim, adicione herança de AnyObject: protocol MyProtocol: AnyObject. Então apenas classes poderão adotar este protocolo. Isto é útil para referências fracas e delegados.

Como verificar conformidade com protocolo em tempo de execução?

Use is para verificar e as? para converter: if let drawable = item as? Drawable. Isto funciona apenas para protocolos sem tipos associados.

Resumo

  • Protocol — um contrato para métodos, propriedades, inicializadores e subscritos
  • Class, struct, enum — todos os tipos podem adotar protocolos
  • Herança de protocolos cria uma hierarquia de contratos sem acoplamento rígido
  • Protocol Composition (&) combina protocolos sem herança
  • Tipos existenciais (any) e tipos opacos (some) — duas formas de trabalhar com protocolos
  • POP é recomendado pela Apple como alternativa à herança clássica de classes
  • Protocol Extensions permitem adicionar implementações padrão

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também