如何在一个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
相关产品推荐
相关产品推荐

