Почему функция Reduction в Swift выдает ошибку «Тип выражения неоднозначен без дополнительного контекста», когда все типы определены правильно? - PullRequest
0 голосов
/ 14 сентября 2018
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)
}

Для всех трех подходов я получаю следующую ошибку:

Тип выражения неоднозначный без контекста

Но, глядя на документацию и сигнатура метода Reduce:

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

Вы можете видеть, что как Result, так и Element могут быть правильно выведены.Результат явно имеет тип [Int], а элемент имеет тип [Int].

Так что я не уверен, что не так.Я также видел здесь , но это тоже не помогает

1 Ответ

0 голосов
/ 14 сентября 2018

Вы правы, что вы передаете правильные типы, которые будут выведены. Ошибка вводит в заблуждение .

Если бы вы вместо этого написали:

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

Тогда компилятор выдал бы ошибку исправить :

Невозможно использовать мутирующий член внеизменное значение: «массив» является константой «let»

Итак, теперь мы знаем, какой должна быть правильная ошибка:

То есть и Результат, и Элемент являются неизменяемыми внутризакрытиеВы должны думать об этом, как обычный func add(a:Int, b:Int) -> Int, где a и b оба неизменны.

Если вы хотите, чтобы он работал, вам просто нужна временная переменная:

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

Также обратите внимание, что неверно!

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

Почему?

Поскольку тип _total.append(element) равен Void, это функция.Его тип не , как тип 5 + 3 т.е. Int или [5] + [3] т.е. [Int]

Следовательно, вам нужно сделать:

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