Why does Swift's reduce function throw an error of 'Type of expression ambigious without more context' when all types are properly defined?

感情迁移 提交于 2019-12-13 05:13:01

问题


var nums = [1,2,3]

let emptyArray : [Int] = []
let sum1 = nums.reduce(emptyArray){ $0.append($1)}
let sum2 = nums.reduce(emptyArray){ total, element in
    total.append(element)
}
let sum3 = nums.reduce(emptyArray){ total, element in
    return total.append(element)
}

For all three approaches I'm getting the following error:

Type of expression ambiguous without more context

But looking at documentation and the method signature of reduce:

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

You can see that both the Result and Element can be correctly inferred. Result is obviously of type [Int] and Element is of type [Int].

So I'm not sure what's wrong. I also saw here but that doesn't help either


回答1:


You're right that you're passing the correct types to be inferred. The error is misleading.

Had you instead wrote:

func append<T>(_ element: T, to array: [T]) -> [T]{
    let newArray = array.append(element)
    return newArray
} 

Then the compiler would have given the correct error:

Cannot use mutating member on immutable value: 'array' is a 'let' constant

So now we know what the correct error should have been:

That is both the Result and the Element are immutable within the closure. You have to think of it just like a normal func add(a:Int, b:Int) -> Int where a & b are both immutable.

If you want it to work you just need a temporary variable:

let sum1 = nums.reduce(emptyArray){
    let temp = $0
    temp.append($1)
    return temp
}

Also note that the following is is wrong!

let sum3 = nums.reduce(emptyArray){ total, element in
    var _total = total
    return _total.append(element)
}

Why?

Because the type of _total.append(element) is Void it's a function. Its type is not like the type of 5 + 3 ie Int or [5] + [3] ie [Int]

Hence you have to do:

let sum3 = nums.reduce(emptyArray){ total, element in
    var _total = total
    _total.append(element)
    return _total
}


来源:https://stackoverflow.com/questions/52323529/why-does-swifts-reduce-function-throw-an-error-of-type-of-expression-ambigious

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!