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

Rust带泛型的自定义宏报错:expected one of @ or |, found : 求解

Rust自定义宏编译错误:expected one of @ or |, found : 的原因与解决方法

问题描述

我尝试在Rust中编写如下自定义宏:

macro_rules! custom_macro {
    ($gen: ident) => {
        let value: MyCustomType<$gen> = Deserialize::deserialize(data)?;

        // 此处为其他代码
    };
}

但编译时let ...行抛出错误:error: expected one of @ or |, found :。以下是更贴近实际场景的完整示例:

macro_rules! custom_macro {
    ($gen: ident) => {
        let value: MyCustomType<$gen> = todo!();

        Ok(())
    };
}

struct MyCustomType<T>(T);
struct Inner;
struct Outer;

pub async fn my_func(flag: bool) -> Result<(), std::error::Error> {
    match flag {
        true => custom_macro!(Inner),
        false => custom_macro!(Outer),
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    my_func(true)
}

原因分析

这是macro_rules!宏的解析机制导致的问题:当宏展开体中出现<时,宏处理器会默认将其视为宏模式语法的一部分(比如用于重复匹配的$(...)*结构),而非普通Rust代码中用于类型参数的括号。此时处理器会按照宏模式的规则解析后续内容,当它遇到类型注解的:时,就会触发语法错误——因为宏模式里<之后只允许出现@(绑定模式)或|(分支模式)。

解决方法

有两种可靠的方式让宏处理器正确识别<>是普通代码的类型参数语法:

方法1:使用Turbofish语法

通过::<>明确标记类型参数,避免宏处理器混淆:

macro_rules! custom_macro {
    ($gen: ident) => {
        let value: MyCustomType::<$gen> = todo!();

        Ok(())
    };
}

方法2:用大括号包裹类型

将类型部分放在大括号中,强制宏处理器按普通Rust代码解析内部内容:

macro_rules! custom_macro {
    ($gen: ident) => {
        let value: { MyCustomType<$gen> } = todo!();

        Ok(())
    };
}

完整修正代码

同时修复原示例中main函数无法直接调用async函数的问题:

macro_rules! custom_macro {
    ($gen: ident) => {
        let value: MyCustomType::<$gen> = todo!();

        Ok(())
    };
}

struct MyCustomType<T>(T);
struct Inner;
struct Outer;

pub async fn my_func(flag: bool) -> Result<(), std::error::Error> {
    match flag {
        true => custom_macro!(Inner),
        false => custom_macro!(Outer),
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 使用Runtime阻塞执行async函数
    tokio::runtime::Runtime::new()?.block_on(my_func(true))?;
    Ok(())
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:20:22