Generics em Swift: para que servem e como usar

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
```html

O que são Generics em Swift e para que servem



Generics (programação genérica) é um dos recursos mais poderosos da linguagem Swift. Eles permitem escrever código flexível e reutilizável que funciona com qualquer tipo de dado, mantendo a tipagem forte. Em vez de criar funções ou estruturas separadas para Int, String, Double e outros tipos, você escreve um código universal que se adapta ao tipo específico durante a compilação.



Imagine que você precisa escrever uma função que troca dois valores. Sem Generics, você teria que criar sobrecargas para cada tipo:



func swapInts(_ a: inout Int, _ b: inout Int) {    let temp = a    a = b    b = temp}

func swapStrings(_ a: inout String, _ b: inout String) { let temp = a a = b b = temp}


Com Generics, isso é feito em uma única linha:



func swapValues<T>(_ a: inout T, _ b: inout T) {    let temp = a    a = b    b = temp}

var x = 10, y = 20swapValues(&x, &y) // funciona com Int

var str1 = "Hello", str2 = "World"swapValues(&str1, &str2) // funciona com String


Principais vantagens dos Generics



  • Segurança de tipos: o compilador verifica os tipos em tempo de compilação, eliminando erros em tempo de execução
  • Reutilização de código: código escrito uma vez funciona com qualquer tipo
  • Desempenho: Generics em Swift são implementados em nível de compilador, sem perda de velocidade de execução
  • Legibilidade: reduz a duplicação de código, tornando-o mais conciso


Funções Genéricas e Parâmetros de Tipo



Uma função genérica é declarada usando colchetes angulares <>, dentro dos quais é especificado o parâmetro de tipo (geralmente denotado pela letra T, mas qualquer nome pode ser usado). O parâmetro de tipo se torna um placeholder, que é substituído pelo tipo real quando a função é chamada.



Exemplo: encontrar um elemento em um array



func findIndex<T: Equatable>(of value: T, in array: [T]) -> Int? {    for (index, element) in array.enumerated() {        if element == value {            return index        }    }    return nil}

let numbers = [1, 5, 3, 12, 7]if let index = findIndex(of: 12, in: numbers) { print("Índice do número 12: \\(index)") // Índice do número 12: 3}

let names = ["Ana", "Boris", "Victor"]if let index = findIndex(of: "Boris", in: names) { print("Índice do nome Boris: \\(index)") // Índice do nome Boris: 1}


Observe a restrição T: Equatable. Isso é uma type constraint — exigimos que o tipo T suporte o protocolo Equatable, caso contrário a operação de comparação == seria impossível.



Tipos Genéricos: Structs, Classes e Enums



Generics funcionam não apenas com funções, mas também com tipos personalizados. Isso permite criar contêineres de dados universais.



Criando uma Stack Genérica



Um exemplo clássico é a estrutura de dados Stack (pilha), que funciona com qualquer tipo:



struct Stack<Element> {    private var items: [Element] = []        mutating func push(_ item: Element) {        items.append(item)    }        @discardableResult    mutating func pop() -> Element? {        return items.popLast()    }        func peek() -> Element? {        return items.last    }        var isEmpty: Bool {        return items.isEmpty    }}

// Usovar intStack = Stack<Int>()intStack.push(10)intStack.push(20)print(intStack.pop() ?? "") // 20

var stringStack = Stack<String>()stringStack.push("Swift")stringStack.push("Generics")print(stringStack.pop() ?? "") // Generics


Enums Genéricos



Enums também podem ser ```

Blogs

Book Recommendations