Swift 4中使用Reduce合并类中Int属性报错求助
解决Swift 4中Reduce处理对象Int属性的闭包参数错误
我来帮你搞定这个Swift 4里reduce的报错问题~你遇到的Contextual closure type '(_, Test) -> _' expects 2 arguments, but 1 was used in closure body错误,核心原因是Swift 4对reduce方法的闭包参数要求更严格,和Swift 3的写法有细微差异,尤其是处理自定义对象属性的聚合场景时。
先理清错误的根源
假设你的Test类是类似这样的:
class Test { let value: Int init(value: Int) { self.value = value } } let testArray = [Test(value: 1), Test(value: 2), Test(value: 3)]
如果你的写法是下面这种错误形式:
// ❌ 错误写法:把累计值当成了Test对象,闭包只用到了一个参数 let total = testArray.reduce(0) { $0.value + $1 }
就会触发报错——因为reduce的闭包必须接收两个参数:第一个是累计值(这里是Int类型的总和),第二个是当前遍历到的Test对象,你混淆了两者的身份,才导致参数数量不匹配。
正确的写法示范
要正确聚合Test对象的value属性,你需要在闭包里明确区分两个参数:
// ✅ 写法1:用明确的参数名,可读性更高 let total = testArray.reduce(0) { currentTotal, testItem in currentTotal + testItem.value } // ✅ 写法2:用简写参数($0是累计值,$1是当前Test对象) let total = testArray.reduce(0) { $0 + $1.value }
这样就能正确计算所有Test对象的value总和了。
为什么Swift 3的写法可能在Swift 4失效?
Swift 4对reduce的类型推断做了优化,不再允许模糊的参数使用逻辑——在Swift 3里,某些宽松的写法可能能通过编译,但Swift 4会严格检查闭包的参数数量和类型,强制你正确区分累计值和当前遍历的元素。
扩展:其他常见reduce聚合场景
如果你要做的不是求和,而是其他聚合操作,逻辑是完全一致的,只要明确闭包的两个参数:
// 拼接所有value的字符串 let valueString = testArray.reduce("") { $0 + "\($1.value), " } // 求value的最大值 let maxValue = testArray.reduce(Int.min) { max($0, $1.value) }
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

