Uma string é uma sequência de caracteres, mas na memória ela é uma sequência de bytes interpretada por uma codificação (UTF-8, UTF-16). Isso explica a maioria das surpresas com texto.
Imutáveis
Em Go e em Java, strings são imutáveis: “alterar” uma string cria outra. Isso as torna seguras para compartilhar entre threads e usar como chave de mapa.
O tamanho depende do que você conta
| Linguagem | Representação | "é" | "😀" |
|---|---|---|---|
| Go | bytes em UTF-8 | len("é") = 2 bytes | len("😀") = 4 bytes |
| Java | unidades UTF-16 | "é".length() = 1 | "😀".length() = 2 |
Para contar caracteres como uma pessoa contaria:
utf8.RuneCountInString("olá") // 3 (len("olá") é 4)for i, r := range "olá" { // range percorre runes, não bytes fmt.Println(i, string(r))}"😀".codePointCount(0, "😀".length()); // 1Concatenar em laço
Como cada concatenação cria uma string nova, juntar milhares de pedaços com + copia tudo de novo a cada volta. Use um builder:
var b strings.Builderfor _, name := range names { b.WriteString(name) b.WriteString(", ")}result := b.String()var sb = new StringBuilder();for (String name : names) { sb.append(name).append(", ");}String result = sb.toString();Para juntar com separador, os dois têm atalho: strings.Join(names, ", ") e String.join(", ", names).
Comparar em Java: equals, não ==
== compara se são o mesmo objeto; equals compara o conteúdo. Às vezes == “funciona” por causa do string pool, o que torna o erro difícil de achar. Em Go, == compara o conteúdo.
Veja também: strings, runes e bytes em Go e Tipos de dados.