如何在宏中包含另一个宏?

问题描述 投票:0回答:1

我尝试编写一个简单的宏,但调用时出现错误“Expected Macro Expand to Produce an Expression”。

宏观实现

public struct Log14: ExpressionMacro {
    public static func expansion(
        of node: some FreestandingMacroExpansionSyntax,
        in context: some MacroExpansionContext
    ) -> ExprSyntax {
        return
"""
if #available(iOS 14.0, *) {
    os_log(.debug, "\\(0)")
}
"""
    }
}
ios swift macros
1个回答
0
投票

#available
不是宏。它看起来像一个宏,因为它也以
#
开头,但它只是一个指定可用性的特殊语法。它不会扩展到任何东西 - 编译器经过硬编码以特殊对待这些。

问题不在于将宏放在宏中。将另一个宏放入宏的扩展中将按照您期望的方式工作。

这里的问题是

if #available(iOS 14.0, *) {
    os_log(.debug, "\(0)")
}

不是一个表达式。您的

ExpressionMacro
应该扩展为一个表达式。这里的
if
是一个声明

独立宏现在无法生成语句。现在解决这个问题的一种方法是生成一个立即调用的闭包表达式。也就是说,将其作为扩展返回:

"""
{
    if #available(iOS 14.0, *) {
        os_log(.debug, "\\(0)")
    }
}()
"""

这不适用于任何类型的语句,即对范围敏感的语句,如

return
defer
break
等。但对于 if 语句,这种解决方法有效。

© www.soinside.com 2019 - 2024. All rights reserved.