【发布时间】:2015-12-03 03:59:06
【问题描述】:
考虑输入Foo:
class Foo {
var isBaz: Bool {
return false
}
func bar() {
print("some boring print")
}
}
现在假设我想遍历一个类实例的集合并在每个实例上调用一些函数:
let someFoos: [Foo] = [Foo(), Foo(), Foo()]
someFoos.forEach { $0.bar() }
这个语法相当紧凑,但感觉有点别扭。此外,它不能在任何地方使用。例如,在if 语句条件中:
if someFoos.contains { $0.isBaz } {
// compiler error: statement cannot begin with a closure expression
}
if someFoos.contains($0.isBaz) {
// compiler error: anonymous closure argument not contained in a closure
}
if someFoos.contains({ $0.isBaz }) {
// this is correct, but requires extra pair of parentheses
}
理想情况下,写类似的东西会很好
someFoos.forEach(Foo.bar)
但从 Swift 2.1 开始,这不是正确的语法。这种引用函数的方式类似于以下:
func bar2(foo: Foo) -> Void {
print("some boring print")
}
someFoos.forEach(bar2)
有没有更好的方法来引用实例函数?你喜欢怎样写这样的表达方式?
【问题讨论】:
-
不清楚问题出在哪里。
someFoos.forEach { $0.bar() }到底有什么不喜欢的?还不清楚您的if构造的目的是什么。 -
@matt
someFoos.forEach { $0.bar() }很好,但 IMO 之类的someFoos.forEach(Foo.bar)会更好(更容易阅读)。if语句只是为了说明在某些情况下需要额外的括号才能使用someFoos.forEach { $0.bar() }语法,这会降低代码的可读性。 -
@deville 但是你回答了你自己的问题。
bar()是 Foo 的一个实例方法。 -
实例方法是将实例作为第一个参数的柯里化函数。所以
someFoos.forEach { Foo.bar($0)() }编译并工作。 – 您的“所需”someFoos.forEach(Foo.bar)与someFoos.forEach { Foo.bar($0) }相同,后者不同且无法编译 -
我认为您将两个问题混为一谈:#1:如何在闭包中将实例方法用作柯里化函数,以及 #2:为什么尾随闭包语法在 if 语句中不起作用. – 也许你应该把这些问题分开。