Uma string em Go é uma sequência imutável de bytes, normalmente texto UTF-8. Os operadores trabalham sobre a própria string (+, ==, <, indexação, fatiamento), e todo o resto fica no pacote padrão strings.
Dividindo strings
| Função | Divide em | Observações |
|---|---|---|
Split(s, sep) | cada sep | mantém partes vazias; Split("", ",") devolve [""], uma string vazia |
SplitN(s, sep, n) | no máximo n partes | a última parte guarda o resto |
SplitAfter(s, sep) | cada sep | mantém o separador em cada parte |
Fields(s) | sequências de espaço em branco | nunca devolve partes vazias |
FieldsFunc(s, f) | caracteres em que f é true | separadores personalizados |
Cut(s, sep) | só o primeiro sep | devolve antes, depois e se encontrou (Go 1.18) |
O caso Split("", ",") pega muita gente: uma entrada vazia gera um slice de tamanho 1, não 0. Ao dividir entrada do usuário, usar Fields ou verificar s == "" antes evita um elemento vazio fantasma.
strings.Cut é o jeito mais limpo de dividir chave=valor, usuario@host e pares parecidos. O Go 1.24 também trouxe versões com iterador, strings.SplitSeq e strings.FieldsSeq, que entregam as partes uma a uma sem montar um slice.
Buscando
| Função | Devolve |
|---|---|
Contains(s, sub) | true se sub aparece em s |
ContainsAny(s, chars) | true se algum caractere de chars aparece |
HasPrefix(s, p) / HasSuffix(s, p) | true se s começa ou termina com p |
Index(s, sub) | posição em bytes da primeira ocorrência, ou -1 |
LastIndex(s, sub) | posição em bytes da última ocorrência, ou -1 |
Count(s, sub) | número de ocorrências sem sobreposição |
EqualFold(a, b) | igualdade sem diferenciar maiúsculas e minúsculas |
Toda busca diferencia maiúsculas de minúsculas, exceto EqualFold. Para buscar sem diferenciar, passe os dois lados para minúsculas ou use EqualFold em comparações de string inteira.
Transformando
Uma armadilha: Trim, TrimLeft e TrimRight recebem um conjunto de caracteres, não um prefixo. strings.TrimLeft("abcab", "ab") remove todos os a e b do começo e devolve "cab". Para remover um prefixo ou sufixo exato, use TrimPrefix e TrimSuffix.
Concatenação e strings.Builder
+ junta strings, e fmt.Sprintf formata valores em uma só. Os dois alocam uma string nova a cada vez, porque strings são imutáveis. Isso não é problema para poucas operações e é lento dentro de um laço, em que cada += copia tudo o que já foi montado. Use strings.Builder no lugar:
Um strings.Builder zero já está pronto para uso. Ele implementa io.Writer, então fmt.Fprintf escreve direto nele. Chame b.Grow(n) antes se você souber mais ou menos o tamanho do resultado. Não copie um Builder depois de escrever nele; passe um ponteiro.
Strings multilinha e raw strings
Go tem dois tipos de literal de string:
Strings entre aspas duplas processam escapes (\n, \t, \", \\, \u00e9) e precisam caber em uma linha. Raw strings entre crases tomam tudo ao pé da letra, incluindo quebras de linha, e por isso são a forma de escrever strings multilinha, expressões regulares, JSON e caminhos do Windows. Uma raw string não pode conter crase, e os retornos de carro (carriage return) dentro dela são descartados. Repare que a query acima começa com uma quebra de linha, já que o literal começa logo depois da crase de abertura.
Tamanho, indexação e substrings
len(s) é o número de bytes. s[i] é um byte, e s[i:j] é uma substring por posições em bytes:
ï e é ocupam dois bytes cada, então a string tem 12 bytes e 10 caracteres. Fatiar por bytes é seguro desde que as posições venham de strings.Index ou funções parecidas, que devolvem offsets em bytes nas fronteiras entre caracteres. Para pegar "os n primeiros caracteres", converta antes para []rune. A página de runes e bytes explica o UTF-8 a fundo.
Strings são imutáveis
Você não pode alterar um byte no lugar: s[0] = 'H' é erro de compilação (cannot assign to s[0] (neither addressable nor a map index expression)). Toda função de strings devolve uma string nova. Para editar, converta para []byte ou []rune, altere o slice e converta de volta:
b := []byte("hello")
b[0] = 'H'
s := string(b) // "Hello"
A imutabilidade também explica por que substrings são baratas: s[2:5] compartilha memória com s em vez de copiar. O outro lado é que uma substring pequena de uma string enorme mantém a string enorme inteira viva. Use strings.Clone (Go 1.20) quando for guardar um pedaço curto de uma entrada grande.
Comparando strings
== e != comparam o conteúdo, e <, > comparam byte a byte, o que dá ordem alfabética para ASCII. strings.Compare existe, mas raramente é necessário; slices.Sort em um []string usa <. Para ordenar texto em outros idiomas respeitando as regras locais, use golang.org/x/text/collate.
Convertendo outros tipos
Números viram strings com strconv.Itoa, strconv.FormatFloat ou fmt.Sprintf, e strings viram números com strconv.Atoi e strconv.ParseFloat. Não escreva string(42): isso gera o caractere com code point 42, "*". A página de conversão de tipos tem a tabela completa.
Perguntas frequentes
Como dividir uma string em Go?
Use strings.Split(s, sep): strings.Split("a,b,c", ",") devolve ["a" "b" "c"]. Para dividir em qualquer sequência de espaços em branco e descartar partes vazias, use strings.Fields(s). strings.SplitN limita o número de partes, e strings.Cut divide uma vez só, em volta do primeiro separador.
Como escrever uma string de várias linhas em Go?
Use uma raw string entre crases:
query := `SELECT id, name
FROM users
WHERE active = true`
Tudo entre as crases é tomado ao pé da letra, incluindo quebras de linha e barras invertidas. Uma raw string não pode conter uma crase.
Como verificar se uma string contém uma substring em Go?
strings.Contains(s, substr) devolve um bool. Funções relacionadas: strings.HasPrefix, strings.HasSuffix, strings.Index (posição ou -1), strings.ContainsAny (qualquer caractere de um conjunto) e strings.EqualFold para igualdade sem diferenciar maiúsculas e minúsculas.
Qual o jeito mais rápido de concatenar strings em Go?
Para poucas strings, + resolve. Quando for montar uma string dentro de um laço, use strings.Builder: chame WriteString várias vezes e String() uma vez no final. += repetido em um laço copia a string inteira a cada vez, então fica lento conforme a string cresce. Para juntar um slice com separador, use strings.Join.
Por que len devolve o tamanho errado da minha string?
len(s) devolve o número de bytes, não de caracteres. Strings em Go são UTF-8, em que caracteres fora do ASCII ocupam de 2 a 4 bytes, então len("héllo") é 6. Use utf8.RuneCountInString(s) para obter o número de code points Unicode.