如何使用可变参数宏调用嵌套构造函数?

2024-05-19

我正在尝试在 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)如果你想。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用可变参数宏调用嵌套构造函数? 的相关文章

随机推荐