You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何macro_rules中用$path::item访问子项会触发语法错误?

问题原因

虽然宏展开后的代码outer::inner::f()语法合法,但macro_rules的片段解析机制在展开前会进行语法检查:$path:path捕获的是一个完整的路径语法节点,在宏定义中直接写$path::f()时,编译器无法将后续的::f()与前面的$path路径节点正确关联——因为path类型的片段本身已经是一个完整的语法单元,后续的::不符合Rust对路径片段后续语法的预期,因此触发编译错误。

解决方法

以下几种方案可以解决这个问题:

方案1:使用Token Tree(tt)捕获

tt是最通用的片段类型,可以捕获任意令牌序列,不会有路径片段的语法限制:

mod outer {
    pub mod inner {
        pub fn f() {}
    }
}

macro_rules! call_f {
    ($($tt:tt)*) => {
        $($tt)*::f()
    };
}

fn main() {
    call_f!(outer::inner);
}

方案2:通过临时导入避免直接拼接路径

利用use将捕获的路径导入为临时名称,再通过临时名称调用函数:

mod outer {
    pub mod inner {
        pub fn f() {}
    }
}

macro_rules! call_f {
    ($path:path) => {
        {
            use $path as temp_module;
            temp_module::f()
        }
    };
}

fn main() {
    call_f!(outer::inner);
}

方案3:捕获分隔的标识符序列

如果确定传入的是由::分隔的标识符,可以直接捕获标识符序列:

mod outer {
    pub mod inner {
        pub fn f() {}
    }
}

macro_rules! call_f {
    ($($ident:ident)::+) => {
        $($ident)::+::f()
    };
}

fn main() {
    call_f!(outer::inner);
}

内容的提问来源于stack exchange,提问作者BallpointBen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:12:14