String vs str em Rust: por que iniciantes se confundem e como entender de uma vez por todas
\n\nSe você está começando a aprender Rust, com certeza já passou por esta situação: o compilador reclama, você tenta passar um String onde se espera &str, ou vice-versa. Familiar? Esta é uma das perguntas mais populares no Stack Overflow (milhares de visualizações!), e não é à toa — o tópico é realmente fundamental para entender o gerenciamento de memória em Rust.
Neste artigo, vamos entender as diferenças entre String e &str, quando usar cada tipo e como evitar erros típicos. Vamos lá!
Resposta rápida para quem está com pressa
\n\nSe você precisa agora — lembre-se do principal:
\n\n- \n
String— é um tipo de dados proprietário, mutável e dinâmico, armazenado no heap. \n&str— é uma fatia de string imutável (slice) que referencia dados pertencentes a outra pessoa. Geralmente aparece como&str. \n
Agora vamos nos aprofundar.
\n\nO que é String em Rust?
\n\nString é um tipo que possui seus próprios dados. Quando você cria uma String, a memória é alocada no heap, e a string pode crescer, diminuir ou ser modificada.
let mut s = String::from("Olá");\ns.push_str(", mundo!");\nprintln!("{}", s); // Exibirá: Olá, mundo!\n\nAqui, s é o proprietário da string. Quando s sai de escopo, a memória é automaticamente liberada (graças ao RAII — Resource Acquisition Is Initialization).
Características principais de String:
\n- \n
- Possui os dados (owning type) \n
- Mutável (mutable) \n
- Armazenada no heap \n
- Pode ser criada a partir de um literal de string:
String::from("texto")\n - Suporta concatenação, inserção e remoção de caracteres \n
O que é &str em Rust?
\n\n&str (pronuncia-se "str-slice" ou "string-slice") é uma referência a uma sequência de caracteres UTF-8 que pertence a outra pessoa. Por si só, &str é apenas um ponteiro para os dados e um comprimento.
let saudacao: &str = "Olá";\nprintln!("{}", saudacao);\n\nNeste exemplo, saudacao é uma referência a um literal de string armazenado diretamente no arquivo binário do programa (no segmento de memória somente leitura). saudacao não possui esses dados — apenas os observa.
Características principais de &str:
\n- \n
- Não possui os dados (borrowed type) \n
- Imutável (immutable) \n
- Armazenada no binário (literais de string) ou no heap (como fatia de uma
String) \n - Leve — consiste em dois campos: ponteiro + comprimento (16 bytes em sistemas de 64 bits) \n
- Ideal para passar para funções quando não é necessário modificar a string \n
Diferenças principais entre String e &str (tabela)
\n\nVamos resumir tudo em uma tabela visual:
\n\n| Característica | \nString | \n&str | \n
|---|---|---|
| Propriedade | \nPossui os dados | \nEmpresta os dados | \n
| Mutabilidade | \nSim (mut) | \nNão | \n
| Onde é armazenada | \nHeap | \nHeap, pilha ou binário | \n
| Tamanho na pilha | \n24 bytes (ptr + len + cap) | \n16 bytes (ptr + len) | \n
| Criação | \nString::from("...") | \n"..." ou &s[..] | \n
| Uso principal | \nQuando é necessário modificar ou possuir a string | \nQuando é necessário apenas ler ou passar como referência | \n
Continue lendo para exemplos práticos e dicas de boas práticas!