我正在try 用Rust创建一个宏,让我可以编写

make_list!(1, 2, 3)

而不是

Node::new(1, Node::new(2, Node::new(3, None)))

它适用于任意数量的"参数",包括零.这就是我目前的情况:

macro_rules! make_list(
    () => (
        None
    );
        ( $x:expr, $( $more:expr ),* ) => (
        Node::new($x, make_list!( $( $more ),* ))
    )
);

但我得到了以下错误:

error: unexpected end of macro invocation
  --> src/main.rs:19:42
   |
19 |             Node::new($x, make_list!( $( $more ),* ))
   |                                          ^^^^^

我搞不懂这个.据我所知,它应该是有效的.我做错了什么?

完整代码:

type List<T> = Option<Box<Node<T>>>;

struct Node<T> {
    value: T,
    tail: List<T>,
}

impl<T> Node<T> {
    fn new(val: T, tai: List<T>) -> List<T> {
        Some(Box::new(Node::<T> {
            value: val,
            tail: tai,
        }))
    }
}

macro_rules! make_list(
    () => (
        None
    );
    ( $x:expr, $( $more:expr ),* ) => (
        Node::new($x, make_list!( $( $more ),* ))
    )
);

fn main() {
    let _list: List<i32> = make_list!(1, 2, 3, 4, 5, 6, 7, 8, 9);
}

推荐答案

进一步讨论错误:我们将讨论只有一个值的情况,因此它写入make_list!(1).但是,没有与之匹配的规则,因为第二个规则在使用表达式x之后,需要一个逗号,但没有提供逗号.

所以你需要让它工作make_list!(1)年,而不仅仅是(实际上,只有not年)make_list!(1,)年.要实现这一点,请在重复部分中使用逗号,如下所示:

macro_rules! make_list(
    () => (
        None
    );
    ( $x:expr $( , $more:expr )* ) => (
        Node::new($x, make_list!( $( $more ),* ))
    )
);

奖励:如果你愿意,你可以写make_list![1, 2, 3]而不是make_list!(1, 2, 3).

Rust相关问答推荐

使用nom将任何空白、制表符、白线等序列替换为单个空白

如何在rust中有条件地分配变量?

为什么我们不能通过指针算法将Rust原始指针指向任意地址?'

如何在Rust中获得不可辩驳的'if let'模式警告Mutex锁定?""

将已知大小的切片合并成一个数组,

如何循环遍历0..V.len()-1何时v可能为空?

当对VEC;U8>;使用serde_json时,Base64编码是保护空间的好方法吗?

Rust函数的返回值不能引用局部变量或临时变量

Rust proc_macro 和 syn:解析空格

使用 pyo3 将 Rust 转换为 Python 自定义类型

为什么需要静态生命周期以及在处理 Rust 迭代器时如何缩小它?

仅在使用 &mut 或线程时borrow 的数据在闭包之外转义?

需要一个有序向量来进行 struct 初始化

为什么 Rust 字符串没有短字符串优化 (SSO)?

Rust中如何实现一个与Sized相反的负特性(Unsized)

Rust/Serde/HTTP:序列化`Option`

为什么 for_each 在释放模式(cargo run -r)下比 for 循环快得多?

以 `static` 为前缀的闭包是什么意思?我什么时候使用它?

判断 is_ok 后重用结果

匹配结果时的简洁日志(log)记录