UTF-8 e Indexação
O str do Rust é UTF-8. A indexação s[i] é baseada em bytes e falha em limites de caracteres inválidos.
Receita
fn safe_prefix(s: &str, max_bytes: usize) -> &str {
if s.len() <= max_bytes { return s; }
let mut end = max_bytes;
while !s.is_char_boundary(end) { end -= 1; }
&s[..end]
}Quando usar isso: Truncar strings de UI, analisar protocolos, qualquer substring por comprimento.
Exemplo de Trabalho
fn main() {
let s = "Hello 🦀";
// let bad = &s[0..7]; // pode falhar
for (i, ch) in s.char_indices() {
println!("{i}: {ch}");
}
}O que isso demonstra:
char_indicesfornece o índice de byte no limite do caractere- Emojis usam 4 bytes em UTF-8
- Fatiamento seguro apenas em
is_char_boundary
Mergulho Profundo
len() retorna bytes. Use chars(), bytes() ou graphemes (crate unicode-segmentation) para caracteres percebidos pelo usuário.
Armadilhas
- Acesso ao caractere s[n] - Não disponível. Correção:
s.chars().nth(n). - Assumir 1 byte por caractere - Incorreto para UTF-8. Correção: Iterar caracteres.
- Truncamento no meio de um codepoint -
strinválido se for forçado. Correção:is_char_boundary. - OsString não é UTF-8 - Bytes da plataforma. Correção: Tipo separado.
- Índice de byte do usuário - Perigoso. Correção: API de índice de caractere/grafema.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
chars().nth | Caractere por índice | Necessita de caractere aleatório O(1) |
unicode-segmentation | Grafemas do usuário | Apenas ASCII interno |
Vec<char> | Índice de caractere repetido | Overhead de memória aceitável |
FAQs
por que não s[i]?
Índice de caractere O(1) impossível em UTF-8.is_char_boundary?
Verificar antes de fatiar em um índice de byte.chars nth O(n)?
Sim, varredura linear.codificar utf16?
Iterador `encode_utf16`.from_utf8?
Valida bytes para `&str` Result.lossy?
Substituição de caractere `String::from_utf8_lossy`.tempo de vida da referência str?
Emprestado de String ou estático.caminho rápido ascii?
Verificação `is_ascii` para otimizar.serde str?
Strings JSON UTF-8.clippy?
`indexing slices` às vezes avisa sobre `str`.Relacionados
Versões do Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.