如何创建转发参数的Swift宏?自定义@publiclyInitializable宏参数未生效
解决@publiclyInitializable宏参数不生效的问题
你想要把@MemberwiseInit(.public, _optionalsDefaultNil: true)做成固定参数的别名宏,但之前的代码因参数类型不匹配或传递逻辑问题导致设置未生效。下面提供两种可靠的实现方式:
方式一:自定义转发宏(推荐)
这种方式通过编写简单的宏实现,直接调用第三方宏并传入固定参数,完全符合"别名"需求,无需用户传参。
1. 宏定义代码
@attached(member, names: named(init)) public macro publiclyInitializable() = #externalMacro( module: "YourMacroModuleName", // 替换为你的宏模块名称 type: "PubliclyInitializableMacro" )
2. 宏实现代码
import SwiftSyntax import SwiftSyntaxMacros import MemberwiseInitMacros // 导入第三方宏包 public struct PubliclyInitializableMacro: MemberMacro { public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { // 构造第三方宏需要的固定参数 let accessLevelExpr = ExprSyntax("AccessLevelConfig.public") let optionalsDefaultNilExpr = ExprSyntax("true") // 构造第三方宏的属性语法结构 let memberwiseInitAttr = AttributeSyntax( attributeName: IdentifierTypeSyntax(name: "MemberwiseInit"), argumentClause: .argumentClause( arguments: LabeledExprListSyntax { LabeledExprSyntax(expression: accessLevelExpr) LabeledExprSyntax( label: IdentifierSyntax("_optionalsDefaultNil"), colon: ColonSyntax(), expression: optionalsDefaultNilExpr ) } ) ) // 调用第三方宏的生成逻辑并返回结果 return try MemberwiseInitMacro.expansion( of: memberwiseInitAttr, providingMembersOf: declaration, in: context ) } }
方式二:匹配原宏参数的别名宏
如果不想自定义宏实现,可以直接让别名宏的参数类型、默认值与第三方宏完全匹配,确保参数能正确传递。
修改后的宏定义代码:
@attached(member, names: named(init)) public macro publiclyInitializable( _ accessLevel: AccessLevelConfig = .public, _deunderscoreParameters: Bool = false, // 严格匹配原宏的参数类型和默认值 _optionalsDefaultNil: Bool = true ) = #externalMacro( module: "MemberwiseInitMacros", type: "MemberwiseInitMacro" )
注意:参数类型(比如用
Bool而非Bool?)必须和第三方MemberwiseInit宏的参数定义完全一致,否则原宏会忽略你的参数,使用自身默认值。
内容的提问来源于stack exchange,提问作者Guig
相关产品推荐
相关产品推荐

