chain
将它们连接成一个迭代器:let v = vec![0, 1, 2, 3, 4, 5, 6];
let start_index = 2;
for e in v[start_index..].iter().chain(v[..start_index].iter()) {
println!("{}", e);
}
take()
来限制它:fn cycle<T>(slice: &[T], start_pos: usize) -> impl Iterator<Item = &T> {
slice.iter().cycle().skip(start_pos).take(slice.len())
}
fn cycle<T>(slice: &[T], start_pos: usize) -> impl Iterator<Item = &T> {
slice[start_pos..].iter().chain(&slice[..start_pos])
}
let v = vec![0, 1, 2, 3, 4, 5, 6];
assert_eq!(cycle(&v, 2).copied().collect::<Vec<_>>(), vec![2, 3, 4, 5, 6, 0, 1]);
cycle().skip().take()
解决方案的开销非常小。对于切片,Iter
类型特殊处理 nth()
(由 skip()
默认实现使用),因此不需要循环,而 Cycle
具有智能的 advance_by()
实现(由 nth()
的默认实现使用)。开销根本不取决于实际索引 - 它是恒定的,编译器甚至可能能够消除它。 - Sven Marnachtake()
,它似乎如此明显 :-) 最后,我还需要添加一个 enumerate()
,其中包含“原始”索引,这样可以很好地配合使用。 - Troels
Iterator::chain
将两个部分连接起来呢?例如: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=16cee881bd70ef5675e5caa6f89872d9 - Masklinn.cycle().skip().take(v.len())
? - user4815162342