Introdução: por que o Go reclama dos seus dados?
\nImagine: você está programando em Go, tudo indo bem, mas de repente o compilador exibe uma mensagem gelada: cannot convert data (type interface {}) to type string: need type assertion. Familiar? Se você trabalhou com Go por pelo menos uma semana, esse erro certamente já te visitou. Ele assusta iniciantes, mas na verdade é uma porta para o mundo do type assertion — um dos mecanismos mais poderosos e ao mesmo tempo traiçoeiros da linguagem.
Neste artigo, não vamos apenas analisar o erro. Vamos entender por que o Go é tão rigoroso, como converter corretamente interface{} para string e outros tipos, e como não cair na armadilha do panic. Pronto? Vamos lá.
O que é interface{} e por que é complicado?
\nEm Go, interface{} (interface vazia) é um tipo que pode armazenar um valor de qualquer tipo. Parece mágica, mas isso tem um custo: Go não permite simplesmente pegar e atribuir um valor de interface{} a uma variável de tipo específico. A linguagem exige uma confirmação explícita: "Ei, eu sei exatamente que dentro disso há uma string, permita-me extraí-la".
Essa confirmação é chamada de type assertion (afirmação de tipo). Sem ela, o compilador exibe exatamente o erro:
\nvar data interface{} = "hello"\n// Erro:\nstr := data // cannot use data (type interface{}) as type string\n\nPor quê? Porque data é uma caixa preta. O compilador não sabe o que está lá dentro. Pode ser uma string, pode ser um número, ou até uma struct. Segurança em primeiro lugar.
Type Assertion: salvador ou fonte de pânico?
\nType assertion é uma sintaxe que permite "verificar" e "extrair" o valor de interface{}. Ela se parece com isso:
str := data.(string)\n\nMas há um detalhe: se data não for uma string, seu programa entrará em pânico. É por isso que desenvolvedores experientes usam a forma com verificação (comma ok idiom):
str, ok := data.(string)\nif !ok {\n // Trata o erro: não é uma string\n fmt.Println("Erro: os dados não são uma string")\n return\n}\nfmt.Println(str)\n\nAgora, se data for um número, o programa não entrará em pânico, apenas informará o erro. Sempre use a forma com verificação se não tiver 100% de certeza sobre o tipo.
Exemplo da vida real: analisando JSON com interface{}
\nO cenário mais comum onde nosso erro ocorre é ao trabalhar com JSON. Quando você analisa um JSON sem uma estrutura rígida, o Go transforma tudo em map[string]interface{}. E é aí que a diversão começa.
Suponha que temos um JSON:
\n{\n "name": "Alice",\n "age": 30\n}\n\nAnalisamos ele:
\njsonStr := `{"name": "Alice", "age": 30}`\nvar result map[string]interface{}\njson.Unmarshal([]byte(jsonStr), &result)\n\n// Tentando obter name\nname := result["name"].(string) // Funciona, mas é perigoso\nfmt.Println(name) // Alice\n\n// Tentando obter age como string — pânico!\nage := result["age"].(string) // panic: interface conversion: interface {} is float64, not string\n\nPor que o pânico? Porque números em JSON são analisados por padrão como float64, e não como string. Conclusão: nunca faça type assertion sem verificação.
Código correto:
\nif name, ok := result["name"].(string); ok {\n fmt.Println("Name:", name)\n}\nif age, ok := result["age"].(float64); ok {\n fmt.Println("Age:", int(age))\n}\n\n\nType Switch: quando há muitos tipos
\nÀs vezes você não sabe qual tipo está dentro de interface{}. Para esses casos, o Go oferece o type switch — uma construção que verifica todas as possibilidades:
var data interface{} = getSomeData()\n\nswitch v := data.(typ