我发现了一个例外,我真的很喜欢 setter only 变量,即当我将闭包作为方法中的唯一参数传递时,其唯一目的是保存它以供以后执行。
我将其实现为如下方法:
typealias ThemeSetter = () -> ()
class Theme {
fileprivate var themeSetters:[ThemeSetter] = []
class var shared: Theme {
struct Singleton {
static let instance = Theme()
}
return Singleton.instance
}
...
func setColor(_ entry:@escaping ThemeSetter) {
entry()
themeSetters.append(entry)
}
}
然后我可以按如下方式调用该方法:
Theme.shared.setColor({
self.navigationBar.barTintColor = Theme.shared.gameBarTint
})
但我不喜欢右括号后的右括号,因为我可能在闭包中有很多行。
因此,了解尾随闭包后,我可以将代码更改为如下所示:
Theme.shared.setColor() {
self.navigationBar.barTintColor = Theme.shared.gameBarTint
}
这完全没问题,也是 Apple 为尾随闭包展示的语法。由于只有一个参数并且我是极简主义者,因此我很想使代码更精简并将其简化为:
Theme.shared.setColor {
self.navigationBar.barTintColor = Theme.shared.gameBarTint
}
这又是 Apple 展示尾随闭包的方式;除此之外,这种方式通常用于某种 Predicate,其中闭包用于告诉方法如何进行排序,或者在异步函数调用结束时将闭包用作完成闭包。我想要的是将闭包分配给...某物。
如果我用变量替换 setColor 的方法,它看起来像这样:
var setColor:ThemeSetter? {
didSet {
if setColor != nil {
setColor?()
themeSetters.append(setColor!)
setColor = nil
}
}
}
现在调用看起来像这样:
Theme.shared.setColor = {
self.navigationBar.barTintColor = Theme.shared.gameBarTint
}
等号表示所有的差异。它表明我正在分配一个闭包并且没有运行一些使用该闭包的函数,即使它确实如此。 :')
最后说明:这实际上与闭包无关,它只是展示了如何创建一个只有 setter 的变量,但它仍然返回 nil。这并不意味着保护类不让用户像真正的 setter 那样访问变量以进行读取。另外,请原谅关于尾随闭包和单例的教程。
我可能没有获得足够的投票来成为正确答案,但为什么正确答案是“不,你不能!你必须使用方法调用!”。我说,“Ni”,谁需要所有的语法。只需使用一个变量,不要读回它,或者如果你这样做,不要让它返回任何东西。有点像鲁道夫·亚当科维奇的回答,得到了 0 票。