我在Swift 3
func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
{
ordersStore.fetchOrders { (orders: () throws -> [Order]) -> Void in
do {
let orders = try orders()
completionHandler(orders)
} catch {
completionHandler([])
}
}
}
_ completionHandler
中的fetchOrders
参数是什么意思?(orders: () throws -> [Order])
是什么意思? PS:我是iOS
和Swift
答案 0 :(得分:8)
这里有很多,所以我们一次打破一件:
func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
fetchOrders
的函数。completionHandler
)并且不返回任何内容。_
表示没有"外部名称"第一个参数。也就是说,你不必标记它(事实上,你不能)。 (由于微妙的原因,这里并不重要,我相信作者在那里使用_
时犯了一个错误,我不会这样做。)completionHandler
是"内部名称,"函数内部调用了什么参数。completionHandler
的类型为(_ orders: [Order]) -> Void
。我们现在打破这种局面。
[Order]
(Order
数组)并返回Void
。非正式地,这意味着"什么都不返回"但字面意思是它返回空元组()
。_ orders:
语法实际上是评论。原则上_
是一个外部名称(但它是闭包的唯一合法外部名称),而orders
是一个内部名称,但实际上,闭包参数没有名称以任何有意义的方式,所以这纯粹是信息性的。orders
告诉我们的不过是[Order]
,我会省略它,并将类型设为([Order]) -> Void
。现在我们转向下一行:
ordersStore.fetchOrders { (orders: () throws -> [Order]) -> Void in
fetchOrders
上的ordersStore
方法。我们可以从这段代码中看出fetchOrders
采用了一个闭包参数。这被称为"尾随封闭" Swift中的语法,这就是为什么我不会使用_
作为闭包的原因。使用尾随闭包语法,不需要参数的外部名称。{ orders in
,但读者可能会对这个有点不寻常的代码感到惊讶。
orders
的闭包,它不接受任何操作并返回[Order]
或抛出错误。基本上这是说fetchOrders
可能失败的一种方式。throws
系统中的尴尬问题,该系统没有自然的方式来表达可能失败的异步操作。这是解决它的一种方法;你通过投掷(即可能失败)的功能。我不赞成这种方法,我赞成在这种情况下使用Result
枚举,因为我认为它可以更好地扩展并避免可能的意外副作用,但这是一个值得商榷的问题(并且Swift社区没有& #39;我真的决定如何处理这个常见问题。)这一切都引导我们:
do {
let orders = try orders()
completionHandler(orders)
} catch {
completionHandler([])
}
orders
闭包的地方。 (这非常重要;如果orders
有副作用,这就是它们发生的时间,这可能与预期的队列不同。这是我不喜欢这种模式的一个原因。 )如果闭包成功,我们返回结果,否则我们会在[]
下面返回catch
。
throws
方法略显愚蠢,因为它甚至在没有日志消息的情况下默默地展平为[]
。如果我们不关心错误,那么失败应该刚刚返回[]
开始而不是与throws
混淆。但是其他呼叫者可能会检查错误。completionHandler
闭包,将其链接回原始调用者。这个do / catch块可以更简单地写成:
let completedOrders = try? orders() ?? []
completionHandler(completedOrders)
通过将错误转换为可选错误,我们更清楚地忽略了错误,并避免了对completionHandler
调用的代码重复。
(我只是添加额外的let
绑定,以使代码更容易阅读;不需要它。)
答案 1 :(得分:2)
completionHandler
参数表示期望参数(名为completionHandler
)必须是一个获取Order
个对象列表且不返回任何值的函数。
答案 2 :(得分:2)
completionHandler
是变量名。在此特定示例中,此变量是callback。你知道是一个回调函数,因为(orders: [Order]) -> Void
是它的数据类型;在这种特殊情况下,所述数据类型是一个函数,它接收变量Order
中的_orders
个对象数组,并且没有返回值(Void
部分)。
TL; DR:
Order
数组作为参数并充当回调函数。