Swift 5.4中的新功能: 现在可以创建一个局部变量,并将其分配给具有相同名称的表达式,而不必手动用self 来消除歧义。
例如,下面的ItemListViewController 有一个方法,可以让我们为给定的IndexPath 检索一个Item ,我们选择简单地称之为item(at:) :
class ItemListViewController: UIViewController {
...
private func item(at indexPath: IndexPath) -> Item {
...
}
}
在使用 Swift 5.3 和更早的版本时,如果我们想调用上述方法,并将其结果分配给一个本地let 或var ,该方法也被称为item ,那么我们就必须在方法调用前加上self ,以便编译器能够将两者分开--像这样:
class ItemListViewController: UIViewController {
...
private func showDetailViewForItem(at indexPath: IndexPath) {
let item = self.item(at: indexPath)
...
}
}
然而,从Swift 5.4开始,这不再是必需的,编译器现在会自动理解右边的item 符号是指对我们方法的调用,不管我们是否用self 来引用它。
class ItemListViewController: UIViewController {
...
private func showDetailViewForItem(at indexPath: IndexPath) {
let item = item(at: indexPath)
...
}
}
也许我最喜欢的使用这种新语法特性的方式是在为异步代码编写单元测试时,这通常涉及使用内置的expectation API创建XCTestExpectation 实例。因为这种期望的最自然的名称通常是简单的expectation ,现在能够做到这一点真是太好了:
class ItemLoaderTests: XCTestCase {
...
func testLoadingItem() {
let expectation = expectation(description: "Loading item")
...
}
}
上述功能可以派上用场的另一种情况是,当我们想创建一个本地的、可变的属性副本时。现在也可以做到这一点,在引用我们要复制的属性时,不必使用self ,例如像这样:
struct Item {
var title: String
var prefix: String?
var suffix: String?
func fullTitle() -> String {
var title = title
if let prefix = prefix {
title = prefix + title
}
if let suffix = suffix {
title += suffix
}
return title
}
}
当然,这可能不是一个革命性的新语法功能,不会完全改变我们编写Swift代码的方式--但是,不是每一个功能或变化都需要如此。我个人认为,这类 "生活质量 "的改进是非常受欢迎的,它可以使某些类型的代码感觉更轻盈。