简体   繁体   English

()在Swift中是什么意思?

[英]What does () mean in Swift?

I have the following function in Swift 3 我在Swift 3具有以下功能

func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
  {
    ordersStore.fetchOrders { (orders: () throws -> [Order]) -> Void in
      do {
        let orders = try orders()
        completionHandler(orders)
      } catch {
        completionHandler([])
      }
    }
  }
  1. What does _ completionHandler argument in fetchOrders mean? 是什么_ completionHandler在参数fetchOrders是什么意思?
  2. What does (orders: () throws -> [Order]) mean? (orders: () throws -> [Order])是什么意思?

PS : I am new to iOS and Swift PS:我是iOSSwift新手

There's quite a lot in here, so we'll break it down one piece at a time: 这里有很多东西,所以我们一次将其分解:

func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
  • This is a function called fetchOrders . 这是一个名为fetchOrders的函数。
  • It has one parameter ( completionHandler ) and returns nothing. 它只有一个参数( completionHandler ),什么也不返回。
  • The first _ indicates that there is no "external name" of the first parameter. 第一个_表示第一个参数没有“外部名称”。 That is, you do not have to label it (in fact, you cannot). 也就是说,您不必标记它(实际上,您不能)。 (For subtle reasons that don't really matter here, I believe the author made a mistake using _ there, and I would not have done that.) (由于微不足道的原因在这里并不重要,我相信作者在此处使用_犯了一个错误,我不会那样做。)
  • The completionHandler is the "internal name," what the parameter is called inside the function. completionHandler是“内部名称”,即在函数内部调用的参数。
  • The type of completionHandler is (_ orders: [Order]) -> Void . 的类型的completionHandler(_ orders: [Order]) -> Void We'll break that down now. 我们现在将其分解。
    • This value is a closure that takes an [Order] (array of Order ) and returns Void . 此值是一个采用[Order]Order数组)并返回Void的闭包。 Informally this means "returns nothing" but literally means it returns the empty tuple () . 非正式地,这意味着“什么也不返回”,但是从字面上看,它意味着返回空的元组()
    • The _ orders: syntax is in practice a comment. _ orders:语法实际上是注释。 In principle the _ is an external name (but that's the only legal external name for a closure), and orders is an internal name, but in reality, closures parameters do not have names in any meaningful way, so this is purely informational. 原则上, _是外部名称(但这是闭包的唯一合法外部名称), orders是内部名称,但实际上,闭包参数没有任何有意义的名称,因此,这纯粹是信息性的。
    • I believe this is a poor use of the closure parameter commenting system. 我相信这是对闭包参数注释系统的不良使用。 Since orders tells us nothing more than [Order] , I would have omitted it, and made the type just ([Order]) -> Void . 由于orders告诉我们[Order] ,因此我将省略它,而将类型设为([Order]) -> Void

Now we'll turn to the next line: 现在我们转到下一行:

ordersStore.fetchOrders { (orders: () throws -> [Order]) -> Void in
  • This calls the fetchOrders method on ordersStore . 这将调用fetchOrders的方法ordersStore We can tell from this code that fetchOrders takes a closure parameter. 从该代码中我们可以看出fetchOrders一个闭包参数。 This is called "trailing closure" syntax in Swift, and is why I would not have used the _ for our closure. 在Swift中,这称为“跟踪闭包”语法,这就是为什么我不希望使用_进行闭包的原因。 With trailing closure syntax, the external name of the parameter is not needed. 使用结尾闭包语法时,不需要参数的外部名称。
  • The author has provided type information here that probably wasn't necessary, but we can explore it anyway. 作者在此处提供了可能不是必需的类型信息,但无论如何我们可以进行探索。 This could likely have been written as just { orders in , but then the reader would probably have been surprised by this somewhat unusual code. 这可能只写为{ orders in ,但随后读者可能会对这个有点不寻常的代码感到惊讶。
    • We have been passed a closure called orders that takes nothing and returns [Order] or throws an error. 我们一直在通过封闭称为orders是需要任何操作并返回[Order]或抛出一个错误。 Basically this is a way to say that fetchOrders might fail. 基本上,这是说fetchOrders可能失败的一种方式。
    • The author is working around an awkwardness in Swift's throws system, which does not have a natural way to express an asynchronous action that might fail. 作者正在研究Swift的throws系统中的尴尬,该系统没有自然的方式来表达可能失败的异步动作。 This is one way to fix it; 这是修复它的一种方法。 you pass a throwing (ie a possibly failing) function. 您传递了一个throwing(即可能会失败)的函数。 I don't favor this approach, I favor using a Result enum for this case because I think it scales better and avoids possible unintended side effects, but that's a debatable point (and the Swift community hasn't really decided how to deal with this common problem). 我不喜欢这种方法,我喜欢在这种情况下使用Result枚举,因为我认为它可以更好地扩展并避免可能的意外副作用,但这是有争议的一点(Swift社区尚未真正决定如何处理此问题。常见问题)。

This all leads us to: 这一切都导致我们:

  do {
    let orders = try orders()
    completionHandler(orders)
  } catch {
    completionHandler([])
  }
  • This is where the orders closure is evaluated. 这是评估orders关闭的地方。 (This is very important; if orders has side effects, this is when they occur, which may be on a different queue than was intended. That's one reason I don't favor this pattern.) If the closure succeeds, we return its result, otherwise we return [] in the catch below. (这非常重要;如果orders有副作用,那就是它们发生的时间,可能与预期的发生在不同的队列上。这是我不赞成这种模式的原因之一。)如果关闭成功,则返回其结果,否则我们返回[]catch下面。
    • In this particular case, the throws approach is slightly silly, because it's silently flattened into [] without even a log message. 在这种特殊情况下, throws方法有点愚蠢,因为它甚至在没有日志消息的情况下也被悄悄地压平为[] If we don't care about the errors, then failure should have just returned [] to start with and not messed with throws . 如果我们不关心错误,那么失败应该只是返回[]而不是throws But it's possible that other callers do check the errors. 但是其他呼叫者也有可能检查错误。
  • In either case, we call the completionHandler closure with our result, chaining this back to our original caller. 无论哪种情况,我们都将调用带有结果的completionHandler闭包,并将其链接回我们的原始调用方。

This do/catch block could have been more simply written as: 这个do / catch块可以更简单地写为:

let completedOrders = try? orders() ?? []
completionHandler(completedOrders)

This makes it clearer that we're ignoring errors by turning it into an optional, and avoids code duplication of the call to completionHandler . 这使得它更清晰,我们正在将其变成一个可选的忽略错误,避免调用的代码重复completionHandler

(I just add the extra let binding to make the code a little easier to read; it isn't needed.) (我只是添加了额外的let绑定,以使代码更易于阅读;不需要。)

completionHandler参数意味着期望的参数(名为completionHandler )必须是一个接受Order对象列表且不返回任何值的函数。

completionHandler is the a variable name. completionHandler是一个变量名。 In this specific example, this variable is a callback . 在此特定示例中,此变量是callback You know is a callback function because (orders: [Order]) -> Void is it's data type; 您知道这是一个回调函数,因为(orders: [Order]) -> Void是数据类型; in this particular case, said data type is a function that receives an array of Order objects in a variable _orders and doesn't have a return value (the Void part). 在这种特殊情况下,所述数据类型是一个函数,该函数接收变量_ordersOrder对象数组,并且不具有返回值( Void部分)。

TL;DR: TL; DR:

  1. it's the variable name, of type: 它是变量名称,类型为:
  2. function which receives an array of Order as a parameter and acts as a callback. 该函数接收Order数组作为参数并充当回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM