macro_rules! for_in_ifs {
    { { $($code:tt)* } } => { ... };
    {
        $code:tt
        // `for-in-if`主体
        $($tag:lifetime :)? for $i:pat in ($iter:expr) // ⚠️ 此处可以使用`:tt`,但编译器会发警告(不必要的括号)
        if ($cond:expr) // ⚠️ 此处可以使用`:tt`,但编译器会发警告(不必要的括号)
        // 剩余部分
        $($tail:tt)*
    } => { ... };
    {
        $code:tt
        // `for-in`主体
        $($tag:lifetime :)? for $i:pat in ($iter:expr) // ⚠️ 此处可以使用`:tt`,但编译器会发警告(不必要的括号)
        // 剩余部分
        $($tail:tt)*
    } => { ... };
}
Expand description

for-in-if格式

  • 🎯使用类似「列表推导式」的方式组织for循环代码
  • ✨支持类似「列表推导式」的语法,但能在其中运行代码块
  • ⚡基本是零成本抽象:除了for inif外,不会引入任何其它开销
  • 具体应用可见列表推导式宏[list]

§用例与测试

use nar_dev_utils::{for_in_ifs};

// 创建可复用的数组
let mut v = vec![];

// 循环向数组添加元素
for_in_ifs! {
    {
        // ✨可在循环中执行任意代码,就好像它本来就在for循环中一样
        let tuple = (i, j);
        v.push(tuple);
    }
    for i in (1..10)
    for j in (1..10) if (i + j < 4)
}

// 检验 #1
assert_eq!(v, [(1, 1), (1, 2), (2, 1)]);
v.clear();

for_in_ifs! {
    {
        // ✨可以在循环中使用控制语句
        // * ⚠️默认只作用于最内层
        //   * 📄亦即此处`continue 'j`与`continue`等价
        if j > 2 { continue 'j; }
        // * 🚩此`break`导致`(2, 1)`被删去
        if i > 1 { break 'i; }
        v.push((i, j));
    }
    // ✨支持设置循环标签
    'i: for i in (1..10) // * ✨标签语法和普通for如出一辙
    'j: for j in (1..10)
}

// 检验 #2
assert_eq!(v, [(1, 1), (1, 2)]);