Introdução: por que "converter slices de interfaces" é um desafio para todo desenvolvedor Go
\n\nSe você já escreveu código em Go que recebe []interface{} e tentou convertê-lo para []string ou []int, com certeza já se deparou com a mensagem irritante do compilador: cannot convert []interface{} to []string. Esse é um dos problemas mais populares no Stack Overflow, com milhares de visualizações. E não é para menos — à primeira vista, a lógica sugere: "Se cada elemento é um interface{} que armazena uma string, por que não posso simplesmente converter o slice inteiro?"
A resposta está em como o Go lida com tipos e memória. Converter slices de interfaces não é apenas uma questão de casting de tipos, mas sim uma cópia completa dos dados. Neste artigo, vamos dissecar o problema do início ao fim: começando pela teoria, passando por exemplos práticos e terminando com soluções prontas que você pode usar imediatamente em seus projetos.
\n\nA propósito, se você programa em Go e trabalha com tipos de dados indefinidos — como ao fazer parsing de JSON ou processar dados de fontes externas — este tópico é essencial para você. Vamos nessa!
\n\nPor que o Go não permite converter diretamente []interface{} para []T?
\n\nVamos começar com o entendimento fundamental. Em Go, interface{} é um tipo especial que armazena um par: (tipo, valor). Quando você tem um []interface{}, cada elemento ocupa uma quantidade diferente de bytes na memória (dependendo do tipo armazenado). Já []string é um array contínuo de structs string (cada string é um ponteiro para os dados + o comprimento).
Imagine que você tem uma caixa com bolas coloridas de tamanhos diferentes (isso é []interface{}), e precisa transferi-las para uma caixa onde todas as bolas são da mesma cor e tamanho ([]string). Não dá para simplesmente carregar a caixa — é preciso verificar cada bola, retirá-la e colocá-la em uma nova caixa. É exatamente isso que acontece ao converter slices de interfaces.
Ponto-chave: a type assertion (afirmação de tipo) funciona apenas com elementos individuais, não com o slice inteiro. O Go não oferece açúcar sintático para conversão em massa — isso foi feito de propósito para que você controle explicitamente o que acontece com cada elemento.
\n\nExemplo do erro que você provavelmente já viu
\n\npackage main\n\nimport "fmt"\n\nfunc main() {\n data := []interface{}{"maçã", "banana", "cereja"}\n // Erro de compilação:\n // cannot use data (variable of type []interface{}) as type []string in assignment\n // var fruits []string = data\n fmt.Println(data)\n}\n\n\nEste código não será compilado. O compilador Go é rigoroso com tipos, e a conversão implícita de slices de tipos diferentes é proibida. Mesmo que você tenha certeza de que dentro só existem strings.
\n\nA maneira correta: Type Assertion para cada elemento
\n\nA forma mais simples e clara de realizar a conversão de slices de interfaces é percorrer cada elemento em um loop e aplicar a type assertion (afirmação de tipo).
\n\nExemplo básico com type assertion
\n\npackage main\n\nimport "fmt"\n\nfunc converterParaStrings(data []interface{}) []string {\n resultado := make([]string, 0, len(data))\n for _, v := range data {\n // Tentamos afirmar que v é uma string\n if str, ok := v.(string); ok {\n resultado = append(resultado, str)\n } else {\n // Tratamento de erro: o elemento não é uma string\n fmt.Printf("Aviso: elemento %v não é uma string, pulando\\n", v)\n }\n }\n return resultado\n}\n\nfunc main() {\n misturado := []interface{}{"olá", 42, "mundo", true, "golang"}\n strings := converterParaStrings(misturado)\n fmt.Println(strings) /