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

如何创建转发参数的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:58:18