Macro nar_dev_utils::list

source ·
macro_rules! list {
    [ $($e:expr)? ] => { ... };
    [
        ($e:expr) $($tail:tt)*
    ] => { ... };
    [
        $e:literal $($tail:tt)*
    ] => { ... };
    [
        $e:block $($tail:tt)*
    ] => { ... };
    [
        [ $($component:tt)* ] $($tail:tt)*
    ] => { ... };
    [
        $e:ident $($tail:tt)*
    ] => { ... };
}
Expand description

列表推导式

  • 🎯方便函数式构造数组等结构
  • ✨支持类似Python、Julia的列表推导式语法
  • 📌有关「for填充」的语法,可参考for_in_ifs
  • 📄形式:使用vec构造空Vec,然后使用Vec::push向其填充表达式元素
    • list![(表达式) for in (迭代器) ...]
    • list![(表达式) for in (迭代器) if (条件) ...]

§用例与测试

use nar_dev_utils::{list, asserts};

// ✨平凡情况⇒直接解包成`vec!`,零成本抽象
let empty: Vec<i32> = list![];
let one = list![1];

// ✨单个标识符允许不带括号
let evens = list![
    i for i in (0..10) if (i % 2 == 0)
];

// ✨在Python中合法且等价的列表推导式 | 测试所用:Python 3.8+
let range = |start, end| start..end;
let pythonic_list = list![
    ((i, j, k))
    for i in (range(1, 10)) if (i > 1)
    for j in (range(1, 10))
    for k in (range(1, 10)) if (i + j + k < 5)
];

// ✨在Julia中合法且等价的列表推导式 | 测试所用:Julia 1.9+
let julian_list = list![
    [i, j]
    for i in ([0, 1])
    for j in ([0, 1])
    if (i + j < 2)
];

// ✨甚至可以在列表推导式中嵌套代码块
let magicked = list![
    { // 兼容代码块逻辑
        // 甚至可以在此处使用`continue`
        // * 📝本质上就在一个展开的`for`循环里
        if i > 2 { continue; }
        // `break`同理,但【直接使用】只能停止【最里边】的循环
        if j + k > 2 { break; }
        // 返回一个表达式的值
        (i, j, k)
    }
    for i in (1..10) if (i > 1)
    for j in (1..10)
    for k in (1..10)
];

// 检验
asserts! {
    empty => []
    one => [1]
    evens => [0, 2, 4, 6, 8]
    magicked => [(2, 1, 1)]
    pythonic_list => [(2, 1, 1)]
    julian_list => [[0, 0], [0, 1], [1, 0]]
}