Introdução: por que a pergunta "How to assign string to bytes array" é tão popular?
\n\nSe você já programou em Go (Golang) e precisou transformar uma string comum em um array de bytes ([]byte), você não está sozinho. A pergunta "How to assign string to bytes array" no Stack Overflow acumula dezenas de milhares de visualizações. Parece simples, não? É só atribuir. Mas Go é uma linguagem de tipagem forte, e simplesmente atribuir uma string a um slice de bytes não funciona. É preciso conhecer as técnicas corretas.
Neste artigo, vamos abordar a conversão de string em array de bytes em Go. Mostrarei três abordagens principais: desde a mais simples até a super rápida, porém perigosa. Você aprenderá qual método escolher dependendo da tarefa e nunca mais se confundirá com essas conversões.
\n\nVamos lá!
\n\nUm pouco de teoria: por que uma string não é um array de bytes?
\n\nAntes de mergulharmos no código, vamos entender por que Go diferencia esses dois tipos. Esse conhecimento evitará dezenas de bugs.
\n\n- \n
- string em Go é uma sequência imutável (immutable) de bytes. Você não pode alterar um caractere da string por índice. A string é sempre armazenada como um bloco de memória somente leitura. \n
- []byte é um slice mutável (mutable) de bytes. Você pode alterar seu conteúdo, adicionar novos elementos, etc. \n
É justamente por causa dessa diferença de "imutabilidade" que o Go exige uma conversão explícita. Se o compilador permitisse simplesmente atribuir uma string a um array de bytes, você poderia acidentalmente modificar dados "protegidos" da string. Portanto, assign string to bytes array sempre exige uma ação consciente sua.
\n\nAbordagem nº1: Conversão explícita de tipo (A mais simples)
\n\nEsta é a primeira maneira que vem à mente de qualquer iniciante. E funciona!
\n\npackage main\n\nimport "fmt"\n\nfunc main() {\n myString := "Olá, Go!"\n myBytes := []byte(myString)\n\n fmt.Println(myBytes) // [208 159 209 128 ...] — bytes em UTF-8\n fmt.Println(string(myBytes)) // Voltando: "Olá, Go!"\n}\n\n\nVantagens:
\n- \n
- Extremamente simples e legível. \n
- Maneira padrão, compreensível para qualquer desenvolvedor Go. \n
Desvantagens:
\n- \n
- Cria uma nova cópia dos dados na memória. Se a string for muito grande (por exemplo, 10 MB), pode ser custoso em memória e tempo. \n
- Não é adequado para sistemas de alta carga, onde cada nanossegundo importa. \n
Quando usar: Em 90% dos casos. Para aplicações comuns, serviços web e scripts, isso é mais que suficiente. Não otimize onde não é necessário.
\n\nAbordagem nº2: Usando copy() (Controlada)
\n\nÀs vezes, você já tem um array de bytes pré-alocado e deseja preenchê-lo com dados de uma string. É aí que a função copy entra em ação.
package main\n\nimport "fmt"\n\nfunc main() {\n myString := "Go é incrível"\n \n // Criando um slice de bytes com o comprimento necessário\n myBytes := make([]byte, len(myString))\n \n // Copiando os dados da string para o slice\n n := copy(myBytes, myString)\n \n fmt.Printf("Bytes copiados: %d\\n", n) // 13\n fmt.Println(string(myBytes)) // "Go é incrível"\n}\n\n\nObserve: copy copia apenas a quantidade de bytes que cabe no slice de destino. Se o slice de destino for mais curto que a string, apenas seu comprimento será copiado. Isso é mais seguro do que a conversão explícita se você não tiver certeza do tamanho.
Vantagens:
\n- \n
- Controle total sobre o processo de cópia. \n
- Segurança: você não ultrapassa os limites do array. \n
- Pode ser usado para cópia parcial (substring). \n
Desvantagens:
\n- \n
- Requer alocação prévia de memória (
make). \n - Ainda cria uma cópia dos dados.