Swift Dictionary.reduce() - 使用完整语法和短语法报告的迭代次数不同

Swift Dictionary.reduce() - different number of iterations reported using full vs. short syntax

我正在尝试掌握 Swift 的窍门,并且想了解为什么以下两个对字典的方法调用,尽管它们产生相同的输出,但被报告为经历了不同数量的Swift 游乐场的迭代。

var chocolates = ["Ram's Bladder Cup": 1, "Spring Surprise": 2, "Crunchy Frog": 3]

let chocolatesString = chocolates.reduce("", combine: {[=12=] + "\(.0), "})
// The Playground says (4 times)

let newerChocolatesString = chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in
return sum + "\(keyValue.0), "
// The Playground says (3 times)

print(chocolatesString)
print(newerChocolatesString)
// The output from both is however identical and as expected...

如果能理解这一点,我将不胜感激 - 我可以明显看出结果没有差异,但我想了解为什么 Playground 报告存在差异。

var chocolates = ["Ram's Bladder Cup": 1, "Spring Surprise": 2, "Crunchy Frog": 3]

let chocolatesString = chocolates.reduce("", combine: {
    [=10=] + "\(.0), "        // (3 times)
})
let newerChocolatesString = chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in
    return sum + "\(keyValue.0), "
    // The Playground says (3 times)
}

    print(chocolatesString)
    print(newerChocolatesString)
// The output from both is however identical and as expected...

..这个数字不反映迭代次数,它反映表达式求值的次数

只要一行代码在执行期间 "visited" 不止一次,Playgrounds 就会使用 "n times" 符号。发生这种情况代替了显示结果,因为执行了不止一次的行——或者执行了多个语句的行——可以有多个结果。

当闭包体在自己的行上时,playground 报告该行执行了 3 次。当闭包主体与它传递给的 reduce 调用在同一行时,它说“4 次”,因为该行代码在执行期间 "visited" 4 次——一次用于 reduce 调用自身,闭包体再调用 3 次。

请注意,无论您使用哪种闭包语法,都会发生这种情况 — 这完全取决于您放置换行符的位置。

chocolates.reduce("", combine: {
    [=10=] + "\(.0), "  // (3 times)
})

chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in
    return sum + "\(keyValue.0), "  // (3 times)
}

chocolates.reduce("", combine: {[=10=] + "\(.0), "})
// (4 times)

chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in return sum + "\(keyValue.0), "}
// (4 times)

我前面没有 Xcode,但是 IIRC 即使你用 ; 将多个语句放在一行中,你也会看到这一点。它与闭包语法无关,与换行符和语句有关:

let a = 1 // 1
let b = a + 1 // 2

let a = 1; let b = a + 1 // (2 times)