Here's how to use a Python-like range in Rust.
It can be used as follows.
// for i in range(5):
// print(i)
for i in range!(5) {
println!("{}", i);
}
// for i in range(1, 5):
// print(i)
for i in range!(1, 5) {
println!("{}", i);
}
// for i in range(1, 5, 2):
// print(i)
for i in range!(1, 5, 2) {
println!("{}", i);
}
// for i in range(5, 1, -1):
// print(i)
for i in range!(5, 1, -1) {
println!("{}", i);
}
You can implement a Python-like range with the following macros.
macro_rules! range {
($stop:expr) => {
0..$stop
};
($start:expr, $stop:expr) => {
$start..$stop
};
($start:expr, $stop:expr, -$step:expr) => {
($stop + 1..$start + 1).rev().step_by($step)
};
($start:expr, $stop:expr, $step:expr) => {
($start..$stop).step_by($step)
};
}
It basically returns the same iterator as the Python range function.
When specifying a negative step, step_by ()
can only receive ʻusize, so you need to reverse the iterator with
rev () . Therefore, the presence or absence of
- is judged by pattern matching, and it is decided whether to perform
rev () `.
Therefore, if a variable contains a negative number and is given as a step, it cannot be determined as a negative number by pattern matching, resulting in a compile error.
//Compile error
let x = -1;
for i in range!(5, 1, x) {
println!("{}", i);
}
I would like to know if there is a way to implement this well.
Rust macros have a lot of freedom, so it's a lot of fun.
Recommended Posts