1이 아닌 단계로 Rust에서 범위를 어떻게 반복 할 수 있습니까? 나는 C ++ 배경에서 왔기 때문에 다음과 같은 것을하고 싶습니다.
for(auto i = 0; i <= n; i+=2) {
//...
}
Rust에서는 range
함수 를 사용해야 하는데 사용자 지정 단계를 갖는 데 사용할 수있는 세 번째 인수가없는 것 같습니다. 어떻게 할 수 있습니까?
답변:
range_step_inclusive
그리고 range_step
긴 사라졌다.
Rust 1.28부터는 Iterator::step_by
안정적입니다.
fn main() {
for x in (1..10).step_by(2) {
println!("{}", x);
}
}
.step_by
방법이 안정 될 때까지 원하는 것을 쉽게 수행 할 수 있습니다 Iterator
( Range
어쨌든 실제로 는 무엇입니까 ).
struct SimpleStepRange(isize, isize, isize); // start, end, and step
impl Iterator for SimpleStepRange {
type Item = isize;
#[inline]
fn next(&mut self) -> Option<isize> {
if self.0 < self.1 {
let v = self.0;
self.0 = v + self.2;
Some(v)
} else {
None
}
}
}
fn main() {
for i in SimpleStepRange(0, 10, 2) {
println!("{}", i);
}
}
다른 유형의 여러 범위를 반복해야하는 경우 다음과 같이 코드를 일반화 할 수 있습니다.
use std::ops::Add;
struct StepRange<T>(T, T, T)
where for<'a> &'a T: Add<&'a T, Output = T>,
T: PartialOrd,
T: Clone;
impl<T> Iterator for StepRange<T>
where for<'a> &'a T: Add<&'a T, Output = T>,
T: PartialOrd,
T: Clone
{
type Item = T;
#[inline]
fn next(&mut self) -> Option<T> {
if self.0 < self.1 {
let v = self.0.clone();
self.0 = &v + &self.2;
Some(v)
} else {
None
}
}
}
fn main() {
for i in StepRange(0u64, 10u64, 2u64) {
println!("{}", i);
}
}
무한 루프가 필요한 경우 개방형 구조를 생성하기 위해 상한 검사를 제거하도록 맡기겠습니다.
이 접근 방식의 장점은 for
설탕 처리와 함께 작동하며 불안정한 기능을 사용할 수있게 되더라도 계속 작동한다는 것입니다. 또한 표준을 사용하는 de-sugared 접근 방식과 달리 Range
여러 .next()
호출로 인해 효율성을 잃지 않습니다 . 단점은 반복자를 설정하는 데 몇 줄의 코드가 필요하므로 루프가 많은 코드에만 가치가있을 수 있다는 것입니다.
U
두 번째 옵션에 다른 유형의 추가를 지원하는 유형을 사용할 수 있으며 여전히 T
. 예를 들어 시간과 기간이 떠 오릅니다.
C ++ 코드를 작성합니다.
for (auto i = 0; i <= n; i += 2) {
//...
}
... 러스트에서 다음과 같이 :
let mut i = 0;
while i <= n {
// ...
i += 2;
}
Rust 버전도 더 읽기 쉽다고 생각합니다.
continue
제대로 사용 하기위한 반 직관적 인 바쁜 작업입니다. 할 수 있지만이 디자인은 버그를 유발합니다.
range_step 과 함께 num crate 사용
미리 정의 된 2와 같이 작은 단계로 이동하는 경우 반복기를 사용하여 수동으로 단계를 수행 할 수 있습니다. 예 :
let mut iter = 1..10;
loop {
match iter.next() {
Some(x) => {
println!("{}", x);
},
None => break,
}
iter.next();
}
이것을 사용하여 임의의 양만큼 단계적으로 이동할 수도 있습니다 (확실히 길어지고 소화하기 어려워 짐).
let mut iter = 1..10;
let step = 4;
loop {
match iter.next() {
Some(x) => {
println!("{}", x);
},
None => break,
}
for _ in 0..step-1 {
iter.next();
}
}