Indexação de strings em Rust: 5 erros fatais e como evitá-los

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que o Rust não permite que você simplesmente escreva s[0]?

\n\n

Você está começando a estudar Rust, escrevendo seu primeiro "Hello, world!" e de repente... um erro de compilação. Você tenta obter o primeiro caractere da string, como fez centenas de vezes em Python ou JavaScript, e o compilador exibe algo como the type 'String' cannot be indexed by '{integer}'. Familiar?

\n\n

Esta pergunta é uma das mais populares no Stack Overflow. Milhares de desenvolvedores tropeçam nesta aparente "estranheza" do Rust. Mas, na verdade, por trás disso há uma solução genial e bem pensada que salva seu código de bugs difíceis de encontrar. Neste artigo, analisaremos os principais erros na indexação de strings em Rust e, o mais importante, aprenderemos a fazer isso corretamente.

\n\n

Erro nº1: Tentativa de indexação direta como em C ou Python

\n\n

O primeiro e mais comum erro é tentar escrever let c = my_string[0];. Em Rust, strings não são simplesmente arrays de caracteres ASCII. Elas são armazenadas na codificação UTF-8. E isso muda tudo.

\n\n

Por que isso não funciona?

\n

Imagine que você tem a string "Привет". Ela tem 6 "caracteres" (do ponto de vista humano). Mas na memória do computador, ela ocupa 12 bytes (cada letra cirílica tem 2 bytes). Se o Rust permitisse my_string[0], o que ele retornaria? O primeiro byte (que por si só não significa nada) ou o primeiro caractere? E se a string contivesse emojis, que ocupam 4 bytes? Seria uma confusão total.

\n\n

O Rust garante segurança em nível de compilação. A indexação por número inteiro sempre funciona em O(1) e retorna um único elemento. Mas para UTF-8 isso é impossível: um "caractere" (char) pode ocupar de 1 a 4 bytes. Portanto, o compilador simplesmente proíbe essa operação para que você não obtenha "lixo" acidentalmente ou quebre a codificação.

\n\n
// ❌ Erro de compilação!\nfn main() {\n    let s = String::from("Привет");\n    // let first = s[0]; // error[E0277]: the type 'String' cannot be indexed by '{integer}'\n    println!("Привет, мир!");\n}
\n\n

Erro nº2: Uso ingênuo de slices (fatiamento) sem considerar limites de caracteres

\n\n

Sim, slices funcionam em Rust. Você pode escrever &s[0..5]. Mas se você cair "dentro" de um caractere multibyte, seu programa entrará em pânico (panic) em tempo de execução. Isso é chamado de runtime panic.

\n\n

Exemplo de erro fatal

\n
fn main() {\n    let s = String::from("Здравствуйте"); // 12 caracteres, mas 24 bytes\n    // Vamos tentar pegar os primeiros 3 bytes\n    let slice = &s[0..3]; // 'З' ocupa 2 bytes, 'д' — 2 bytes.\n    // 3 bytes é metade do segundo caractere!\n    println!("{}", slice); // thread 'main' panicked at 'byte index 3 is not a char boundary'\n}
\n\n

Isso não é apenas um aviso. É uma falha completa do programa. O Rust não perdoa trabalho inseguro com memória, nem mesmo em tempo de execução. Se você trabalha com entrada do usuário (apelidos, comentários), você certamente terá esse panic no primeiro caractere cirílico ou asiático.

\n\n

Como evitar: Use o método char_indices() para buscar limites com segurança ou trabalhe através de chars().

\n\n

Erro nº3: Confusão entre bytes, char e grafemas

\n\n

Este é o erro mais traiçoeiro. Mesmo que você aprenda a obter um char de uma string, ainda pode não obter o que esperava. Porque char em Rust é um Unicode Scalar Value. E o que uma pessoa considera um "caractere" (por exemplo, "é" ou "🇷🇺") pode consistir em vários char.

\n\n

Análise com exemplo

\n
fn main() {\n    let s = String::from("é"); // Isso pode ser um único char (U+00E9)\n    // ou composto: 'e' (U+0065) + '◌́' (U+0301)\n    let composed = String::from("e\\u{0301}"); // o mesmo 'é', mas de dois char\n    println!("Tamanho de s: {} bytes, {} char", s.len(), s.chars().count());\n    println!("Tamanho de comp                

Blogs

Book Recommendations