Código de demonstração usando a versãorustc 1.86.0 (05f9846f8 2025-03-31)
fn main() {
let mut source = 1..3;
test(&mut source); // This is good. which means &mut Range<T> is Iterator.
test(&source); // This code error "`&std::ops::Range<{integer}>` is not an iterator"
}
fn test(i: impl Iterator<Item = i32>) {
for i in i {
println!("{}", i);
}
}
Não encontrei o motivo da ferrugem no código fonte.
Iterator
não é implementado diretamente nem para&Range
nem para&mut Range
. Ele é implementado somente paraRange
.No entanto, existe uma implementação geral
impl<I: ?Sized + Iterator> Iterator for &mut I
para qualquer iterador. Uma implementação correspondente não pode ser escrita para referências compartilhadas, porque iteradores requerem referência mutável para avançar (next()
). Embora intervalos (pelo menos de tipos comoi32
) possam ser implementadosIterator
para referências, eles não o fazem — e, portanto, recebem a implementação automática para referência mutável, mas não existe tal correspondência para referências compartilhadas.Isso não tem nada a ver com
Range
. Todas as referências mutáveis a iteradores são implementadasIterator
devido a esta implementação . No entanto, para poder iterar, é necessário mutar o estado do iterador, o que não pode ser feito por meio de uma referência imutável, portanto, não existe tal implementação.