Как пересылать функции с переменными параметрами?
В Swift, как вы преобразовываете массив в кортеж?
Проблема возникла из-за того, что я пытаюсь вызвать функцию, которая принимает переменное количество аргументов внутри функции, которая принимает переменное количество аргументов.
// Function 1
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
// Example Usage
sumOf(2, 5, 1)
// Function 2
func averageOf(numbers: Int...) -> Int {
return sumOf(numbers) / numbers.count
}
Эта реализация averageOf
показалась мне разумной, но она не компилируется. При попытке вызвать sumOf(numbers)
:
появляется следующая ошибка:
Could not find an overload for '__converstion' that accepts the supplied arguments
Внутри averageOf
, numbers
имеет тип Int[]
. Я полагаю, что sumOf
ожидает кортеж, а не массив.
Таким образом, в Swift, как вы преобразовываете массив в кортеж?
Ответы
Ответ 1
Это не имеет ничего общего с кортежами. Во всяком случае, невозможно преобразовать из массива в кортеж в общем случае, поскольку массивы могут иметь любую длину, а arty кортежа необходимо знать во время компиляции.
Однако вы можете решить свою проблему, предоставив перегрузки:
// This function does the actual work
func sumOf(_ numbers: [Int]) -> Int {
return numbers.reduce(0, +) // functional style with reduce
}
// This overload allows the variadic notation and
// forwards its args to the function above
func sumOf(_ numbers: Int...) -> Int {
return sumOf(numbers)
}
sumOf(2, 5, 1)
func averageOf(_ numbers: Int...) -> Int {
// This calls the first function directly
return sumOf(numbers) / numbers.count
}
averageOf(2, 5, 1)
Может быть, есть лучший способ (например, Scala использует специальный тип, чтобы избежать необходимости перегрузки, вы можете писать в Scala sumOf(numbers: _*)
из averageOf
без определения двух функций), но я не знаю Не нашел его в документах.
Ответ 2
Начиная с Swift 4.1 (в Xcode 9.2), нет необходимости перегружать с помощью sumOf (_ numbers: Int...), функция, которая пересылает переменный (-ые) параметр (-ы), НЕЗАКОННО изменяет его на один параметр массива отдельного параметра. (ы). Например, следующий код будет работать без перегрузки:
// This function does the actual work
func sumOf(_ numbers: [Int]) -> Int {
return numbers.reduce(0, +) // functional style with reduce
}
func averageOf(_ numbers: Int...) -> Int {
// This calls the first function directly
return sumOf(numbers) / numbers.count
}
печать (среднее значение (2, 5, 1))
Не знаю, это ошибка компилятора или нет :)
Ответ 3
Я понимаю, что это старая статья, но она оказалась довольно высокой в результатах поиска, и я нашел рабочее решение.
Вы можете написать функцию sumOf для приема массива целых чисел в качестве числового параметра и перегрузить функцию sumOf, чтобы принять переменный ввод для числового параметра, который будет передан первой версии в виде массива. Таким образом, функция AverageOf может передать свой переменный ввод в виде массива в sumOf.
Это не кажется идеальным, потому что вам нужно перегружать каждую функцию, которая работает следующим образом, но она будет работать так, как вы хотели.
func sumOf(numbers: [Int]) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
// Function 1
func sumOf(numbers: Int...) -> Int {
return sumOf(numbers: numbers)
}
// Example Usage
sumOf(2, 5, 1)
// Function 2
func averageOf(numbers: Int...) -> Int {
return sumOf(numbers: numbers) / numbers.count
}
Ответ 4
Я не думаю, что ему нужно использовать .reduce. Вместо этого просто измените определение параметра в его функции sumOf. Вместо:
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
записи:
func sumOf(numbers: [Int]) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}