Introdução: por que saber o tipo de uma variável em Swift?
\nVocê já escreveu código em Swift e de repente se pegou pensando: "Qual é o tipo dessa variável?" Especialmente quando trabalha com Any, genéricos ou heranças complexas. É como tentar adivinhar o que está dentro de uma caixa sem abri-la. Mas no Swift existem ferramentas poderosas que permitem olhar dentro e determinar exatamente o tipo ou classe de uma variável.
Neste artigo, vamos abordar como exibir o tipo de uma variável em Swift, usando type(of:), Mirror, String(describing:) e até mesmo o bom e velho dynamicType (sim, ele ainda existe em código legado). Você aprenderá não apenas a imprimir o tipo, mas também a usar isso em projetos reais: para depuração, registro de logs, verificação de tipos em tempo de execução e trabalho com protocolos.
O artigo foi escrito para o site educacional pythonlib.ru e adaptado para desenvolvedores iniciantes e experientes. Vamos lá!
\n\n1. A maneira mais simples: type(of:)
\nA maneira mais popular e correta de descobrir o tipo de uma variável em Swift é usar a função global type(of:). Ela retorna o metatipo (MetaType) do valor passado.
Exemplo:
\nlet name = "Ana"\nlet age = 25\nlet price: Double = 99.99\nlet isActive = true\n\nprint(type(of: name)) // String\nprint(type(of: age)) // Int\nprint(type(of: price)) // Double\nprint(type(of: isActive)) // Bool\n\nObserve: type(of:) funciona com qualquer tipo — structs, classes, enums, closures. Até mesmo com valores opcionais:
var optionalValue: String? = "Olá"\nprint(type(of: optionalValue)) // Optional<String>\n\n\nPor que type(of:) é a melhor escolha?
\n- \n
- Funciona com value types (structs, enums) e reference types (classes). \n
- Suporta protocolos e genéricos. \n
- Não requer especificação explícita do tipo no código. \n
- Retorna o tipo dinâmico exato (considera herança). \n
2. A maneira clássica: String(describing:)
\nÀs vezes você não precisa apenas saber o tipo, mas transformá-lo em uma string para exibir em um log ou interface. String(describing:) lida muito bem com essa tarefa:
let value: Any = 42\nprint(String(describing: type(of: value))) // Int\n\nPode ser combinado com type(of:) para um registro bonito:
func logType(_ value: Any) {\n let typeName = String(describing: type(of: value))\n print("[LOG] Tipo: \\(typeName), valor: \\(value)")\n}\nlogType(3.14) // [LOG] Tipo: Double, valor: 3.14\n\n\n3. Trabalhando com classes: dynamicType e Mirror
\nAntes do Swift 3, usava-se a propriedade dynamicType. Ela ainda está disponível para compatibilidade reversa, mas oficialmente está obsoleta. No entanto, você pode encontrá-la em projetos antigos:
class Animal {}\nclass Dog: Animal {}\n\nlet pet: Animal = Dog()\nprint(pet.dynamicType) // Dog (sintaxe obsoleta)\n\nA substituição moderna é type(of:):
print(type(of: pet)) // Dog\n\n\nMirror: olhando mais fundo
\nSe você precisa saber não apenas o tipo, mas também a estrutura do objeto (por exemplo, nomes das propriedades), use Mirror:
struct User {\n let name: String\n let age: Int\n}\n\nlet user = User(name: "João", age: 30)\nlet mirror = Mirror(reflecting: user)\nprint(mirror.subjectType) // User\nfor child in mirror.children {\n print("\\(child.label ?? ""): \\(child.value) (\\(type(of: child.value)))")\n}\n// Saída:\n// name: João (String)\n// age: 30 (Int)\n\nIsso é especialmente útil para depurar hierarquias complexas ou ao trabalhar com reflexão.
\n\n4. Determinando a classe para Any e AnyObject
\nEm Swift, o tipo Any é comum — ele pode armazenar um valor de qualquer tipo. Para descobrir o tipo específico