我想定义一个新的宏
@publiclyInitiazable
,它是 这个包中的
@MemberwiseInit(.public, _optionalsDefaultNil: true)
的别名。
我怎样才能轻松做到这一点?我试过了
@attached(member, names: named(init))
public macro publiclyInitializable(
_ accessLevel: AccessLevelConfig = .public,
_deunderscoreParameters: Bool? = nil,
_optionalsDefaultNil: Bool? = true
) =
#externalMacro(
module: "MemberwiseInitMacros",
type: "MemberwiseInitMacro"
)
但是参数没有被应用:
您似乎希望宏具有不同的默认参数。目前,除非您分叉宏的实现,否则这是不可能的。
宏读取其参数的方式与方法读取其参数的方式不同。特别是,宏实现直接从源代码中读取 AST 节点,而不是像调用方法时那样评估参数表达式。您在宏声明中看到的默认参数值根本不会影响宏的扩展方式。它们充其量只是作为文档。
为了使其正常工作,您需要编写自己的宏,该宏可以扩展为
@MemberwiseInit
。然而,从 Swift 6.0 开始,不支持这种宏。您只能使用 MemberAttributeMacro
将属性添加到声明的 members。充其量,您需要一个封闭类型,例如
@publiclyInitializable
public enum EnclosingType {
public struct AnyParams { ... }
}
// expands to
public enum EnclosingType {
@MemberwiseInit(.public, _optionalsDefaultNil: true)
public struct AnyParams { ... }
}
这种封闭类型可能是不可取的,但您可以使用
typealias
来稍微克服这一点。
或者,您可以分叉存储库并更改宏实现。 这是你需要改变的地方。
let configuredAccessLevel: AccessLevelModifier? = extractConfiguredAccessLevel(from: node)
// I have added "?? true" here, so that when this argument cannot be found, it is "true"
// when this argument does exist, and it is "nil", extractLabeledBoolArgument will actually return "false".
// See the implementation of extractLabeledBoolArgument for more details
let optionalsDefaultNil: Bool? =
extractLabeledBoolArgument("_optionalsDefaultNil", from: node) ?? true
let deunderscoreParameters: Bool =
extractLabeledBoolArgument("_deunderscoreParameters", from: node) ?? false
// I have changed this from "?? .internal" to "?? .public"
let accessLevel = configuredAccessLevel ?? .public