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 IndexSoluçã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]); // appleImportante: 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
&stremString.
// ✅ 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
Leia também
Injeção de Dependência em Java: para iniciantes — guia completo
Algoritmos e estruturas de dados em Rust: um guia prático
Reflexão e Introspecção em PHP: Guia Completo com Exemplos
Trimagem de Strings em Swift: existe um método trim() para String?
GraphQL API com C#: tutorial passo a passo para desenvolvedores .NET