6 个版本 (2 个稳定版)
使用旧 Rust 2015
1.1.0 | 2015 年 11 月 14 日 |
---|---|
1.0.0 | 2015 年 5 月 25 日 |
0.2.1 | 2015 年 3 月 2 日 |
0.2.0 | 2015 年 1 月 20 日 |
0.1.1 | 2014 年 11 月 14 日 |
2044 在 Rust 模式 中排名
每月 86 次下载
用于 2 crates
12KB
包含 (ELF 可执行文件/库, 7KB) 一个.out
Rust 的 C 风格 for 循环
一个实现 C 风格 for
循环的 Rust 宏。有关更多信息,请参阅文档。
lib.rs
:
以宏形式实现的 C 风格 for
循环。
其形式为 cfor!(初始化器; 条件; 步长 { 主体 })
。
初始化器
是在循环任何迭代之前评估的语句。在此处声明的任何变量都限于cfor!
调用的作用域内,即在条件
、步长
和主体
内仅可用。条件
是在每次迭代开始时评估的布尔表达式。如果它评估为false
,则迭代将停止。步长
是一个任意表达式,它在每次迭代结束时执行(包括如果调用continue
),在检查条件
之前。
初始化器和条件可以像 C 一样为空,但步长不能。没有步长的 for
循环与 while
循环相同。
何时使用它?
只有在 cfor!
比更声明性的内置 迭代器、它们的适配器 和 for
循环更清晰时,才使用。例如,内置迭代器功能更自包含,因此更不容易在期望 j
的位置不小心写入 i
(我写 C 中的嵌套 "2D" 循环时,经常会因为这个原因而受到影响)。
此外,上述适配器方法允许以无法通过 C 风格迭代实现的方式编写简洁、高效、可重用的 "函数式" 代码。
如何使用它?
将存储库作为正常的 cargo 依赖项添加,并使用以下命令将其包含到您的 crate 中:#[phase(plugin)]
。(请参阅以下示例。)
[dependencies.cfor]
cfor = "1.0"
示例
简单
std::iter
不太自然地处理非加性条件,但可以简单地直接处理。
#[macro_use] extern crate cfor;
fn main() {
cfor!{let mut x = 1; x < 0x1000; x *= 2; {
println!("power of 2: {}", x);
}}
}
体内条件
如果某个条件需要执行一些额外的计算来检查(或者如果有一些代码应该始终被评估,即使对于给定的迭代条件将是 false
),则可以在 cfor
头部省略该条件。
#[macro_use] extern crate cfor;
fn main() {
cfor!{let mut x = 1; ; x *= 2; {
// ... setup ...
println!("handling power of 2: {}", x);
if x < 0x1000 { break }
// ... further handling ...
println!("handling power of 2: {}", x);
}}
}
循环外的初始化
有时,在循环完成后可能希望访问循环外部的变量,因此必须在循环外声明它,或者可能正在遍历一些预先提供的/计算出的值,因此没有有意义的其他初始化。在这种情况下,可以安全地省略初始化表达式。
#[macro_use] extern crate cfor;
extern crate rand;
fn main() {
let mut x = 1u16;
cfor!{; x < 0x1000; x *= 2; {
println!("power of 2: {}", x);
// sometimes quit early
if x > rand::random() { break }
}}
println!("actually stopped at {}", x);
}
处理 continue
(或,“为什么这个宏如此复杂?”)
特别努力确保 continue
正确地工作,以下定义的原始宏会导致 continue
也跳过评估 step
,这可能导致无限循环等不希望的行为。
// WARNING: this is broken.
macro_rules! bad_cfor {
($init: stmt; $cond: expr; $step: expr; $body: block) => {
{
$init;
while $cond {
$body;
$step;
}
}
}
}
fn main() {
let mut true_counter = 0;
bad_cfor!{let mut i = 0; i < 10; i += 1; {
// manually avoid the infinite loop
if true_counter >= 50 { break }
true_counter += 1;
println!("i = {}", i);
// try to skip just i == 4
if i == 4 {
// but this skips the i += 1 leaving us
// on i == 4 forever.
continue
}
// ...more code...
}}
}
它以与 cfor!
相同的方式调用,但如果 $body
包含 continue
,则循环体末尾的 $step
将永远不会被评估。
处理多个初始化和步骤
与 C 循环一样,cfor!
支持使用逗号分隔指定多个初始化和步骤。
#[macro_use] extern crate cfor;
fn main() {
cfor!{let mut x = 0, let mut y = x; x <= 10 && y <= 100; x += 1, y += 10; {
println!("x: {}, y: {}", x, y);
}}
}