Generics em Swift para iniciantes: 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

Introdução: Por que não dá para viver sem Generics em Swift?

Imagine que você precisa escrever uma função que soma dois números. Depois — uma função para somar duas strings. E depois — para arrays. Sem programação genérica (Generics), você teria que criar uma versão separada do código para cada tipo de dado. Isso não só aumenta o volume de código, mas também dificulta sua manutenção.

Generics em Swift — é uma ferramenta poderosa que permite escrever código flexível, reutilizável e type-safe. Eles são a base de estruturas populares como Array, Dictionary e Optional. Neste artigo, vamos entender por que os Generics são necessários, como usá-los na prática e por que todo desenvolvedor iOS/macOS iniciante deve dominar este tópico.

O que são Generics em palavras simples?

Generics — é uma forma de escrever código que funciona com qualquer tipo de dado, sem sacrificar a tipagem forte do Swift. Em vez de especificar um tipo concreto (por exemplo, Int ou String), você usa um placeholder (geralmente a letra T), que é substituído pelo tipo real durante a chamada da função ou criação da estrutura.

O problema sem Generics

Suponha que você escreva uma função para trocar os valores de duas variáveis. Sem Generics, você teria que escrever assim:

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
}

Isso é duplicação evidente. Se precisar trocar Double ou tipos personalizados, a quantidade de funções vai crescer.

Solução com Generics

Uma função universal substituirá todas as anteriores:

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

// Uso:
var x = 10
var y = 20
swapValues(&x, &y) // x = 20, y = 10

var firstName = "Ana"
var lastName = "Ivanova"
swapValues(&firstName, &lastName) // firstName = "Ivanova"

Os colchetes angulares <T> declaram o placeholder do tipo. O compilador determina automaticamente que T é Int no primeiro caso e String no segundo. O código fica conciso e seguro.

Como usar Generics: cenários principais

Generics em Swift são usados em funções, estruturas, classes, enums e protocolos. Vamos ver os casos mais comuns.

1. Funções genéricas

Já vimos o exemplo com swapValues. Mas podemos ir além — criar uma função que encontra o índice de 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, 9, 12]
if let index = findIndex(of: 9, in: numbers) {
    print("Índice: \(index)") // Índice: 2
}

Observe o <T: Equatable>. Isso é uma restrição de tipo (type constraint). Estamos dizendo: "T deve estar em conformidade com o protocolo Equatable para que possamos usar o operador ==". Sem essa restrição, o código não compila.

2. Tipos genéricos (structs e classes)

Vamos criar uma estrutura simples de "Pilha" (LIFO) que pode armazenar qualquer tipo:

struct Stack<Element> {
    private var items: [Element] = []

    mutating func push(_ item: Element) {
        items.append(item)
    }

    mutating func pop() -> Element? {
        return items.popLast()
    }

    func peek() -> Element? {
        return items.last
    }
}

// Uso:
var intStack = Stack<Int>()
intStack.push(1)
intStack.push(2)
print(intStack.pop
```                

Blogs

Book Recommendations