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

zvms9eto  于 5个月前  发布在  Swift
关注(0)|答案(1)|浏览(41)

我尝试编写一个简单的宏,但调用时出现错误“Expected macro expansion 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)")
}
"""
    }
}

字符串

dldeef67

dldeef671#

#available不是一个宏。它看起来像一个宏,因为它也是以#开头的,但它只是一个特殊的语法来指定可用性。它不会扩展到任何东西-编译器被硬编码来特殊对待这些。
问题不在于将宏放在宏中,而是将另一个宏放在宏的扩展中,这将符合您的预期。
这里的问题是

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

字符串
不是一个表达式。您的ExpressionMacro应该扩展为表达式。这里的if是一个 * 语句 *。
独立的宏现在不能生成 * 语句 *。现在解决这个问题的一种方法是生成一个立即被调用的 * 闭包表达式 *。也就是说,将this作为展开返回:

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


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

相关问题