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

如何在一个Macro中引入另一个Macro?调用时遇表达式生成错误

解决Swift Macro报错“Expected macro expansion to produce an expression”

你遇到的问题核心是:Log14实现了ExpressionMacro,但宏返回的是if语句块——而ExpressionMacro要求展开结果必须是表达式,不是语句,这就触发了报错。

两种修正方案:

方案1:继续用ExpressionMacro,将语句转为表达式

Swift中可以用_ = ...把语句包裹成合法的表达式,同时修正参数引用的错误写法:

public struct Log14: ExpressionMacro {
    public static func expansion(
        of node: some FreestandingMacroExpansionSyntax,
        in context: some MacroExpansionContext
    ) -> ExprSyntax {
        // 获取宏调用时传入的第一个参数
        guard let messageExpr = node.arguments.first?.expression else {
            return "()" // 返回空表达式避免报错
        }
        
        return
"""
_ = if #available(iOS 14.0, *) {
    os_log(.debug, "%@", \(messageExpr))
}
"""
    }
}

方案2:改用StatementMacro(适合单独作为语句调用)

如果你的宏只是用来单独执行(比如单独一行#Log14("debug info")),直接实现StatementMacro即可,不需要处理表达式转换:

public struct Log14: StatementMacro {
    public static func expansion(
        of node: some FreestandingMacroExpansionSyntax,
        in context: some MacroExpansionContext
    ) -> StmtSyntax {
        guard let messageExpr = node.arguments.first?.expression else {
            return "{}"
        }
        
        return
"""
if #available(iOS 14.0, *) {
    os_log(.debug, "%@", \(messageExpr))
}
"""
    }
}

额外说明

你原代码里的\(0)写法错误,宏无法直接这样引用参数,必须通过node.arguments提取调用时传入的表达式,再代入到展开结果中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:32:38