Xcode 9.2中为何无法对数组字面量调用reduce(into:)?
解决方案
你可以通过两种方式解决这个编译错误:
1. 显式指定数组字面量的类型
给数组字面量加上类型标注,让编译器先确定数组的元素类型:
([1,2,3] as [Int]).reduce(into: [Int: String](), {$0[$1] = $1.description})
或者用初始化器显式创建数组:
Array<Int>([1,2,3]).reduce(into: [Int: String](), {$0[$1] = $1.description})
2. 给闭包参数添加类型标注
明确闭包中两个参数的类型,帮助编译器理清依赖关系:
[1,2,3].reduce(into: [Int: String](), { (dict: inout [Int: String], num: Int) in dict[num] = num.description })
为什么会出现这个问题?
核心原因是Swift类型推断系统在处理带inout参数的方法时,对数组字面量的推导逻辑存在局限:
- 对于普通的
reduce(_:_:)(比如你例子里的[1,2,3].reduce(0, +)),编译器可以从初始值0先推断出Result类型是Int,再顺推出数组元素的类型也是Int,整个推导链是单向的,没有歧义。 - 但
reduce(into:_:)的闭包接受一个inout Result参数和数组的Element参数,这两个类型的推断是相互依赖的:编译器需要知道数组的Element类型才能确定闭包中第二个参数的类型,同时又需要从闭包的操作中确认Result的类型。当你直接用数组字面量时,这两个推导过程互相“卡壳”,导致编译器无法明确类型,从而抛出歧义错误。
而当你先把数组字面量赋值给一个常量(比如let arr = [1,2,3]),编译器会先把常量的类型确定为[Int],此时调用reduce(into:)时,Element类型已经明确,编译器只需要处理Result类型(也就是你指定的[Int: String]),自然就能正常编译了。
内容的提问来源于stack exchange,提问作者Sweeper
相关产品推荐
相关产品推荐

