我一直在探索仿函数,但在了解forEach
仿函数在幕后所做的工作时遇到了一些麻烦。例如,当我将其输入游乐场时:
let array = [1] // [1]
array.forEach { $0.value } // (3 times)
array.forEach { _ in print("hello") } // (2 times)
当我展开(3 times)
或时,(2 times)
它只是显示()
例如,为什么在1个元素的数组上有多个执行,为什么两个forEach
计算的执行次数不同?
这是一个令人困惑的情况。
让我们考虑第二个forEach
:
array.forEach { _ in print("hello") } // (2 times)
该行的不同部分在不同的时间执行,Swift将这些时间中的每一次都计为一次单独的执行。第一次是在其调用时array.forEach
,第二次是在其内部forEach
执行到print
匿名函数主体中的调用的时间。如果放入换行符,我们可以看到Swift只执行每行一次并报告其“值”:
array.forEach { _ in // [1]
print("hello") // ()
}
我们也可以尝试将匿名函数放在变量中:
let p: (Int) -> () = { _ in print("hello") } // (2 times)
array.forEach(p) // [1]
在上面,Swift执行let p
一次该行的一部分以创建匿名函数并将其存储在中p
,然后再执行该行的另一部分以print
在函数主体内部进行调用。
Swift报告该行的值print
是()
因为forEach
s参数必须是一个返回的函数()
(空元组aka Void
)。由于print
已经返回()
,因此Swift只需将其作为该行的值即可。
在回头考虑您的第一个forEach
示例之前,让我们考虑另一个示例:
print("hello"); print("goodbye") // (2 times)
Swift说这行执行两次,因为该行上的每个单独的语句都算作一个单独的执行。
现在,让我们考虑您的第一个示例:
array.forEach { $0.value } // (3 times)
让我们尝试使用换行符:
array.forEach { // [1]
$0.value // (2 times)
}
好的,因此forEach
调用本身就算是一次执行。但是Swift声称它两次执行匿名函数的主体。为什么?
回想一下,forEach
参数必须是返回的函数()
。但是类型$0.value
不是()
; 它是内部类型Builtin.Int64
。因此,Swift在该行的末尾插入另一个语句,以return ()
。实际上,Swift的行为就像您这样写:
array.forEach { // [1]
$0.value; () // (2 times)
}
我们可以通过向函数显式添加另一行来证明这一点:
array.forEach { // [1]
$0.value // <<<opaque type>>>
()
}
现在,Swift认为每行都按预期执行一次。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句