macros - 为什么此宏调用会导致无法解析的名称?

标签 macros rust

这是我尝试为我正在处理的 RPC 库实现的宏的简化版本:

#[macro_export]
macro_rules! msgpack_rpc {
    (
        $(
            rpc $name:ident ( $( $arg:ident : $arg_ty:ty ),* ) -> $ret_ty:ty | $err_ty:ty;
        )+
    ) => (
        pub trait Service {
            $(
                fn $name ( &self, $( $arg : $arg_ty ),* ) -> Result<$ret_ty, $err_ty>;
            )+
        }

        pub struct Server;

        impl Server {
            pub fn listen<S>(handle: &(), address: (), service: S)
                    -> ::std::io::Result<()>
                    where S: Service + Send + Sync + 'static {
                let service = move |msg: &str| {
                    let result = match msg {
                        $(
                            stringify!($name) => {
                                service.$name($( $arg ),*)
                                    .map(String::from)
                                    .map_err(String::from)
                            }
                        ),+,
                        _ => String::from("method not supported".into()),
                    };
                };

                Ok(())
            }
        }
    )
}

msgpack_rpc! {
    rpc echo(arg: i64) -> i64 | ();
}

宏扩展编译失败并出现此错误:

error: unresolved name `arg` [--explain E0425]
  --> <anon>:40:17
   |>
40 |>     rpc echo(arg: i64) -> i64 | ();
   |>                 ^
<anon>:39:1: 41:2: note: in this expansion of msgpack_rpc! (defined in <anon>)

通过阅读类似的问题,我知道 macro_rules 有时会在扩展语句时出现问题。但是,我对为什么在这种情况下无法扩展项目感到困惑。

是否有解决扩展问题的解决方法?

最佳答案

在调用函数的上下文中没有任何名为 arg 的变量。这是编译器提示的“未解析的 arg”。

stringify!($name) => {
    $( let $arg = Default::default(); )*
    service.$name($( $arg ),*)
        .map(String::from)
        .map_err(String::from)
}

关于macros - 为什么此宏调用会导致无法解析的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39679337/

相关文章:

c++ - 使用宏来专门化 std::swap

generics - Rust 泛型 : Expected <T> found <Foo>

rust - 如何创建一个全局的、可变的单例?

rust - 是否可以预测堆栈溢出?

ms-access - 运行宏/查询后 MS Access 取消选择列表框

c - 将 XOR 作为宏实现,但未按预期工作

macros - 在 Haxe 宏中读取元数据

objective-c - #if 预处理器宏 "running"#ifdef 是 Objective-C 中的后台吗?

rust - 为什么在使用 FlatMap 迭代器时出现 FromIterator<&{integer}> is not implemented for Vec<i32> 错误?

json - 从 JSON 数组中选择键的子集