Подтвердить что ты не робот

Как пересылать функции с переменными параметрами?

В 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, как вы преобразовываете массив в кортеж?

4b9b3361

Ответ 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
}