重命名是一个宏,用于简化符号的重命名。例如,假设你有
struct MyType {
let propertyName: String
}
但是你将 MyType.propertyName
重命名为 MyType.newName
。 为了避免引入破坏性更改,你可以添加一个名为 propertyName
的计算属性,并使用 @available(*, deprecated, renamed: "newName")
进行装饰,但这可能很繁琐。
使用重命名,可以使用单个属性完成此操作。
struct MyType {
@Renamed(from: "propertyName")
let newProperty: String
}
这将生成 Swift 代码
struct MyType {
let newName: String
@available(*, deprecated, renamed: "newName")
var propertyName: String {
newName
}
}
(这不完全是宏的展开方式,但在这里并不重要)。
Renamed
使用与 @available
属性的 renamed
参数相同的命名语法。 例如,也支持重命名函数。
@Renamed(from: "oldFunctionName(argument:_)")
func newFunctionName(_ variableName: String, argumentName: Int) -> Bool {}
产生
func oldFunctionName(argument arg0: String, _ arg1: Int) -> Bool {
newFunctionName(arg0, argumentName: arg1)
}
不带参数的函数可以省略括号
@Renamed(from: "oldFunctionName")
func newFunctionName() -> Bool {}
这适用于
问:这个项目的完成度如何?
目前处于测试阶段,支持最新的 Swift 5.9 快照,专门使用 Xcode 15 beta 进行了测试。可能还有更多可以支持的情况,并且在某些情况下可能会抛出更具描述性的错误(例如,而不是生成无效代码)。
综上所述,所有支持的用例都有相关的测试来证明其有效性。
问:我发现有些东西不起作用。 我能做什么?
答:请提交一个 issue,或者更好的是,提交一个带有失败或实现的 PR。 我相信有一些我没有想到的边缘情况!
问:这会很慢吗?
答:编译时会有少量性能损失,但这是最小的。 生成的代码通常与手动编写的代码相同。 不会添加运行时依赖项。
问:我是否必须添加整个依赖项才能节省一些输入?
答:是的。 就我个人而言,我只会考虑在大型重构中使用此项目。
问:这是类型安全的吗?
答:在某种程度上是。 Swift 将检查此宏生成的代码,因此如果您输入无效名称,例如 @Renamed(from: "1nvalid")
,编译器将抛出错误。 当在不支持的符号(例如没有显式类型的变量)上使用时,该宏也会产生编译时错误。 这些错误正在修复中,并且将支持更多情况。
问:在哪里可以找到有关宏的更多信息?
答: Swift 宏仪表板. CustomHashable.
要使用宏,您需要使用最新的 Swift 工具链。 由于 Xcode 不支持使用工具链构建包,因此开发正在 Visual Studio Code 中进行。 检查 settings.json 文件,以查看项目正在开发的快照。