Swift:$0 在 Array.forEach 中是如何工作的?

Posted

技术标签:

【中文标题】Swift:$0 在 Array.forEach 中是如何工作的?【英文标题】:Swift : How $0 works in Array.forEach? 【发布时间】:2016-07-14 13:20:21 【问题描述】:

我看到大多数 swift 开发人员都开始使用 .forEach,了解它是另一种迭代数组的方式。但是'$0'的含义是什么以及它是如何工作的?如果它是一个索引,那么它应该递增 0,1,2...

@IBOutlet var headingLabels: [UILabel]!
....

headingLabels.forEach  $0.attributedText = NSAttributedString(string: $0.text!, attributes: [NSKernAttributeName: 1]) 

【问题讨论】:

$0 指的是保存在数组中的对象(在您的示例中为 UILabel)。 看起来它正在代替循环中的当前元素。该数字可能表示正在使用的函数的位置参数。 所以你的意思是说 $0 指的是当前对象? 它的意思是简写参数名称 $0 - 代表第一个对象/当前对象 请注意,大多数 Swift 开发人员不应该开始使用.forEach。在某些特定情况下它很有用(特别是在映射/过滤器链的末尾),但它不是for-in 的通用替代品,它更灵活,通常更好的 Swift。特别是,for-in 正确处理了returncontinuebreak,其中forEachreturn 有一些令人惊讶的行为并且不支持其他行为。 【参考方案1】:

简答

看看这段代码

let nums = [1,2,3,4]
nums.forEach  print($0) 

这里是forEach之后的闭包

我的意思是这部分 print($0)

执行 4 次(数组中的每个元素执行一次)。每次执行时,$0 都包含nums 数组的n-th 元素的副本

所以第一次包含1,然后是2等等...

这是输出

1
2
3
4

比较 forEachfor-in 构造

那么我们可以说$0 就像下面代码中的n 值吗?

for n in nums 
    print(n)

是的,意思差不多。

它是如何工作的?

forEach 方法接受一个闭包。闭包有这个签名。

(Self.Generator.Element) throws -> Void

当您使用forEach 时,它会与您签订“合同”。

    您向forEach 提供一个闭包,该闭包接受输入中的单个参数,其中该参数与数组的类型相同 forEach 会将该闭包应用于数组的每个元素。

示例

nums.forEach  (n) in
    print(n)

但是在 Swift 中,您可以省略闭包参数的显式名称。在这个闭包内部,您可以使用$0 作为第一个参数,$1 作为第二个参数,依此类推。

所以前面sn-p的代码也可以写成下面这样

nums.forEach 
    print($0)

【讨论】:

@appzYourFile,合约在后台是如何运作的?你知道我在哪里可以找到这个的来源吗?基本上,我试图弄清楚,当您在类型数组的实例上调用名为 foreach 的方法时,该函数如何知道数组中存在的值,因为我们在该函数中传递的只是一个空的闭包变量。对?每个函数如何实际获取要迭代的数组数据?谢谢! @nitinsh99:看看here。特别是 Inferring Type From ContextShorthand Argument Names 段落 @appzYourLife 很好的解释。我在一次在线 ios 面试测试中看到了这一点。【参考方案2】:

参数的简写名称

Swift 自动为内联提供速记参数名称 闭包,可用于引用闭包的值 名称为 $0、$1、$2 等的参数。

如果您在闭包中使用这些速记参数名称 表达式,你可以省略闭包的参数列表 定义,以及速记参数名称的数量和类型 将从预期的函数类型推断。 in 关键字可以 也可以省略,因为闭包表达式完全由 它的身体:

reversed = names.sort( $0 > $1 ) 这里,$0 和 $1 指的是 闭包的第一个和第二个字符串参数。

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

【讨论】:

就我而言,它总是 $0。但我仍然可以迭代所有元素。 $0 是每次迭代的第一个参数。想像这样的 for 循环: for (index, element) in list.enumerate() print("Item \(index): \(element)") $0 代表元素。您使用它的唯一原因是用更少的行更快地编写代码 在 $0 中,0(零)表示函数/闭包参数的索引,而不是数组中项的索引。这个概念对于 unix shell-script 和 C 开发人员来说很熟悉,其中 arg0 arg1 等表示脚本或函数的参数。【参考方案3】:

“forEach”、“sort”等函数将闭包作为参数。这些闭包也有参数,例如对于“forEach”函数的闭包,您可以提供自己的参数名称,或者使用默认的“$0”。如果闭包有多个参数(如函数“sort”),默认参数将是“$0”,如果您没有提供,则为“$1”。请记住,闭包可以期望您返回一些值,例如“排序”。你明白了,这里是例子:

let array: [String] = []
array.forEach  element in
    element.doStuff()


array.forEach 
    $0.doStuff()


let sortedArray = array.sort  first, second in
    return first < second


let sortedArray = array.sort 
    return $0 < $1

【讨论】:

以上是关于Swift:$0 在 Array.forEach 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

Array.forEach原理,仿造一个类似功能

为啥在 Array.ForEach 输出 333 而不是 0112? [复制]

JavaScript----Array.foreach()

forEach()Array.map()和Array.filter()用法

Array.forEach Array.map Array.filter的用法

jQuery.each 实现不同于原生 Array.forEach