Divisão de string 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

Introdução: por que split() em Rust é um campo minado para iniciantes

Se você migrou para Rust vindo de Python ou JavaScript, a primeira coisa que tentará fazer é escrever "hello,world".split(","). E, muito provavelmente, não obterá o que esperava. No Stack Overflow, a pergunta «How do I split a string in Rust?» acumulou dezenas de milhares de visualizações. O problema não é que Rust esteja "quebrado", mas sim que seu sistema de propriedade e empréstimo exige uma abordagem diferente para uma operação aparentemente trivial.

Neste artigo, analisaremos os 5 principais erros que desenvolvedores cometem ao fazer split de string em Rust e mostraremos como evitá-los. Você aprenderá não apenas a dividir uma string, mas a fazer isso de forma eficiente, segura e elegante.



Erro nº1: Ignorar o tipo do valor retornado

O cenário mais comum: você escreve let parts = s.split(","); e tenta usar parts como um vetor. Rust responde: expected struct 'std::str::Split'.



Qual é o problema?

O método split() retorna um iterador, não uma coleção. Isso é feito por eficiência: o iterador não aloca memória para todas as partes de uma vez, mas as fornece uma a uma. Mas o iniciante espera uma lista familiar.



// ❌ Isso não funcionalet text = "apple,banana,cherry";let parts = text.split(",");println!("{}", parts[0]); // Erro! Split não implementa Index


Solução correta

Colete o iterador em um vetor usando .collect():



// ✅ Corretolet text = "apple,banana,cherry";let parts: Vec<&str> = text.split(",").collect();println!("Primeiro elemento: {}", parts[0]); // apple


Importante: o tipo da variável parts é Vec<&str>. São fatias da string original, não novas strings. Se a string original for deletada, as referências se tornarão inválidas. Sobre isso, no próximo erro.



Erro nº2: Esquecer do tempo de vida (lifetime)

Você obteve um vetor &str, mas tenta retorná-lo de uma função. O compilador reclama sobre lifetime. Vamos analisar o cenário clássico:



// ❌ Erro: retornando referência para string localfn split_csv_bad(line: &str) -> Vec<&str> {    let cleaned = line.trim().to_string(); // nova string    cleaned.split(",").collect() // referências para cleaned, que será destruída}


O compilador Rust é mais esperto que você: ele vê que cleaned será destruído ao sair da função, e as referências no vetor ficarão pendentes.



Como evitar

Existem dois caminhos:

  • Trabalhar com a string original, sem criar novos proprietários.
  • Clonar os dados, transformando &str em String.


// ✅ Opção 1: receber &str e retornar Vec<&str> com o mesmo lifetimefn split_csv_good(line: &str) -> Vec<&str> {    line.split(",").collect()}

// ✅ Opção 2: criar strings própriasfn split_csv_owned(line: &str) -> Vec<String> { line.split(",").map(|s| s.to_string()).collect()}


Escolha a primeira opção se os dados forem necessários apenas dentro do contexto atual. A segunda, se você planeja passá-los para outras threads ou armazená-los por muito tempo.



Erro nº3: Tratamento incorreto de partes vazias

Imagine que você está analisando um CSV com valores ausentes: "apple,,cherry". O método split() retornará honestamente uma string vazia entre as duas vírgulas. Mas isso frequentemente quebra a lógica.



let data = "apple,,cherry";let parts: Vec<&str> = data.split(",").collect();println!("{:?}", parts); // ["apple", "", "cherry"]


O que fazer?

  • Se partes vazias são um erro: use split_terminator() ou filtre:




                
                

Blogs

Book Recommendations