Swift 带参数语法的闭包
Swift closure with parameter syntax
我正在学习 swift,但我一直坚持使用带参数语法的疯狂闭包。以下是执行此操作的“正确方法”。
enum Brew: Int {
case lager
case barleyWine
case porter
}
let beer = { (kind: Brew) -> Void in
print( "\(kind), smooth!")
}
let gin = { () -> Void in
print("gin & juice")
}
func sip( on drink: () -> Void ) {
print("Sip...")
drink()
}
func sip( on drink: (Brew) -> Void ) {
print("Sip...")
drink(brew.porter)
}
sip( on: beer )
sip( on: gin )
这会打印...
Sip...
porter, smooth!
Sip...
gin & juice
但是,这对我来说意义不大。每当我用啤酒调用 sip() 时,它的编码方式就假定它是搬运工。似乎我应该能够在对 sip 的调用中指定 brew 而不是在 sip 定义中。像这样...
sip( on: beer( brew.porter )
这样啤酒闭包在被调用时被参数化。这不是更具可读性和实用性吗?为什么不是这样呢?有实现此功能的语法吗?
此外,是否应该有一种方法可以编写一个带有可变参数的 sip() 方法,以便它可以喝啤酒或杜松子酒?怎么样?
闭包令人困惑!
Also, shouldn't there be a way to write one sip() method with variable parameters so that it can take beer OR gin?
现在,beer
和 gin
是不同类型的闭包(beer
接受参数而 gin
不接受),这就是为什么你需要两个sip
的重载 - 一个来处理每种类型。想象一下,如果有一个 sip
可以同时接受它们,会发生什么。它如何知道是否传递参数?
另一方面,如果您的最终目标是这样的:
sip(on: beer(brew.porter))
然后声明单个 sip
是 可能的。
现在,执行 beer(brew.porter)
将调用 beer
闭包。 beer
闭包 returns Void
和 Void
不能传递到 sip
,所以那是行不通的。你的直觉可能会说“为什么不能 beer(brew.porter)
return 另一个闭包,当没有参数调用时,用波特啤酒喝啤酒?”恭喜,您发现了 currying.
您可以更改 beer
来做到这一点:
let beer = { (kind: Brew) -> (() -> Void) in // a closure that returns a closure!
// return { () -> Void in print("\(kind), smooth!") }
return { print( "\(kind), smooth!") } // short-hand
}
现在你只需要这个 sip
:
func sip( on drink: () -> Void ) {
print("Sip...")
drink()
}
但在现实世界中,您通常无法更改 beer
(因为这是别人的代码,或者没有意义)。在这种情况下,您必须更改调用 sip
:
的方式
// "{}" indicates a closure! You are putting the closure call "beer(brew.porter)" inside another closure.
sip(on: { beer(brew.porter) })
我正在学习 swift,但我一直坚持使用带参数语法的疯狂闭包。以下是执行此操作的“正确方法”。
enum Brew: Int {
case lager
case barleyWine
case porter
}
let beer = { (kind: Brew) -> Void in
print( "\(kind), smooth!")
}
let gin = { () -> Void in
print("gin & juice")
}
func sip( on drink: () -> Void ) {
print("Sip...")
drink()
}
func sip( on drink: (Brew) -> Void ) {
print("Sip...")
drink(brew.porter)
}
sip( on: beer )
sip( on: gin )
这会打印...
Sip...
porter, smooth!
Sip...
gin & juice
但是,这对我来说意义不大。每当我用啤酒调用 sip() 时,它的编码方式就假定它是搬运工。似乎我应该能够在对 sip 的调用中指定 brew 而不是在 sip 定义中。像这样...
sip( on: beer( brew.porter )
这样啤酒闭包在被调用时被参数化。这不是更具可读性和实用性吗?为什么不是这样呢?有实现此功能的语法吗?
此外,是否应该有一种方法可以编写一个带有可变参数的 sip() 方法,以便它可以喝啤酒或杜松子酒?怎么样?
闭包令人困惑!
Also, shouldn't there be a way to write one sip() method with variable parameters so that it can take beer OR gin?
现在,beer
和 gin
是不同类型的闭包(beer
接受参数而 gin
不接受),这就是为什么你需要两个sip
的重载 - 一个来处理每种类型。想象一下,如果有一个 sip
可以同时接受它们,会发生什么。它如何知道是否传递参数?
另一方面,如果您的最终目标是这样的:
sip(on: beer(brew.porter))
然后声明单个 sip
是 可能的。
现在,执行 beer(brew.porter)
将调用 beer
闭包。 beer
闭包 returns Void
和 Void
不能传递到 sip
,所以那是行不通的。你的直觉可能会说“为什么不能 beer(brew.porter)
return 另一个闭包,当没有参数调用时,用波特啤酒喝啤酒?”恭喜,您发现了 currying.
您可以更改 beer
来做到这一点:
let beer = { (kind: Brew) -> (() -> Void) in // a closure that returns a closure!
// return { () -> Void in print("\(kind), smooth!") }
return { print( "\(kind), smooth!") } // short-hand
}
现在你只需要这个 sip
:
func sip( on drink: () -> Void ) {
print("Sip...")
drink()
}
但在现实世界中,您通常无法更改 beer
(因为这是别人的代码,或者没有意义)。在这种情况下,您必须更改调用 sip
:
// "{}" indicates a closure! You are putting the closure call "beer(brew.porter)" inside another closure.
sip(on: { beer(brew.porter) })