Como pular os últimos elementos da string no loop?
Minha solução está funcionando bem
fn main() {
let s = "123456".to_string();
for ch in (&s[..s.len()-1]).chars() { // skip the last element
println!("{}", ch);
}
}
Mas há algo melhor?
Semelhante a skip()
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.skip
que permite pular os primeiros elementos do loop
Você pode usar
next_back
(doDoubleEndedIterator
trait) para remover explicitamente o caractere final antes de iniciar a iteração:Se você precisar remover vários caracteres, basta executar
next_back
um loop de intervalo simples (possivelmente verificando paraNone
permitir que você faça issobreak
imediatamente se tentar pular mais caracteres do que os existentes).Como observei nos comentários , sua solução não é segura na presença de caracteres UTF-8, pois pode dividir os bytes de um único caractere UTF-8. Esta solução é segura, pois
next_back
decodifica e omite corretamente um caractere UTF-8 de qualquer largura.A razão pela qual você não pode fazer algo assim sem operar primeiro de trás para frente é que caracteres UTF-8 de largura variável significam que operando puramente na ordem direta, Rust não tem ideia de quando são
x
caracteres do final da string até chega ao final da corda (ponto em que só poderia saber em retrospectiva). Mesmo quando sabe que faltam quatro bytes para o final, pode ser 1 (um único caractere de quatro bytes), 2 (dois caracteres de dois bytes), 3 (dois caracteres simples e um de dois bytes) ou 4 (quatro caracteres simples) em esse intervalo, e ele deve decodificar para descobrir em qual cenário ele está. SomenteExactSizeIterator
s, que sabem seu comprimento preciso antecipadamente, podem fazer isso com o uso inteligente derev
andskip
, aDoubleEndedIterator
, que é o que.chars()
lhe dá, não pode.Como
.len()
uma string retorna o número de bytes, não o número de caracteres, sua tentativa falhará com caracteres multibyte.Aqui vai uma sugestão: é só atrasar a impressão.