提供以下代码:
[true, true, false, true, true, true, true, true, true, true, true, true, true, true, true]
.reduce(true, {
print("Hello")
return $0 && $1
})
func f(_ a: Bool) -> Bool {
print("World")
return a
}
f(true) && f(false) && f(true) && f(true) && f(true) && f(true) && f(true) && f(true) && f(true)
它为数组中的每个项打印"Hello"
,但仅为前两个函数调用打印"World"
,因为&&
短路。
为什么reduce
不遵循相同的行为?
怎么可以添加这种行为?
注意:即使删除了副作用,闭包也会被调用15次。
答案 0 :(得分:1)
因为今天(2016年),构建一个编译器(在合理的时间内)分析你写入reduce闭包的代码并确定短路逻辑是否适用将是非常困难的。
您提供了一个简单的示例
{
print("Hello")
return $0 && $1
}
但我相信你可以想象更复杂的闭包,这项任务并非无足轻重。
看看这段代码
let text: String
let n = 1
if n > 10 {
text = "greater than 10"
} else {
text = "smaller than 11"
}
print(text)
在最后一行,编译器让我打印text
,因为他知道它将始终填充(无论是执行IF还是ELSE)
现在让我们来看看这个新代码段
let text: String
let n = 1
if n > 10 || n <= 10 {
text = "greater than 10"
}
print(text)
error: constant 'text' used before being initialized
我们知道text
常量将始终填充。
然而,所有编译器都知道,当IF条件为false
时,text
不已填充。