Передача массива в функцию с переменным числом аргументов в Swift


на Язык Программирования Swift Он говорит:

функции также могут принимать переменное количество аргументов, собирая их в массив.

  func sumOf(numbers: Int...) -> Int {
      ...
  }

когда я вызываю такую функцию с разделенным запятыми списком чисел ('sumOf(1, 2, 3, 4), они доступны в виде массива внутри функции.

вопрос: Что делать, если у меня уже есть массив чисел, которые я хочу передать в этом функции?

let numbers = [1, 2, 3, 4]
sumOf(numbers)

это не удается с ошибкой компилятора, "не удалось найти перегрузку для '_ _ conversion', которая принимает предоставленные аргументы". Есть ли способ превратить существующий массив в список элементов, которые я могу передать в вариативную функцию?

6 129

6 ответов:

Splatting еще не на языке, как подтвердили разработчики. Обходной путь на данный момент-использовать перегрузку или ждать, если вы не можете добавить перегрузки.

вот работа вокруг, что я нашел. Я знаю, что это не совсем то, что вы хотите, но это, кажется, работает.

Шаг 1: объявите функцию, которую вы хотели бы с массивом вместо вариативных аргументов:

func sumOf(numbers: [Int]) -> Int {
    var total = 0
    for i in numbers {
        total += i
    }
    return total
}

Шаг 2: вызовите это из вашей вариативной функции:

func sumOf(numbers: Int...) -> Int {
    return sumOf(numbers)
}

Шаг 3: Позвоните В Любом Случае:

var variadicSum = sumOf(1, 2, 3, 4, 5)
var arraySum = sumOf([1, 2, 3, 4, 5])

Это кажется странным, но это работает в моих тестах. Дайте мне знать, если это причиняет непредвиденные проблемы для кого-либо. Свифт, кажется чтобы иметь возможность разделить разницу между двумя вызовами с одинаковым именем функции.

кроме того, с помощью этого метода, если Apple обновляет язык, как предполагает ответ @manojid, вам нужно будет только обновить эти функции. В противном случае, вам придется пройти и сделать много переименований.

вы можете привести функцию:

typealias Function = [Int] -> Int
let sumOfArray = unsafeBitCast(sumOf, Function.self)
sumOfArray([1, 2, 3])

вы можете использовать вспомогательную функцию, как например:

func sumOf (numbers : [Int])  -> Int { return numbers.reduce(0, combine: +) }
func sumOf (numbers : Int...) -> Int { return sumArray (numbers) }

Я сделал это (обертка + сопоставление идентичности):

func addBarButtonItems(types: REWEBarButtonItemType...) {
    addBarButtonItems(types: types.map {  })
}

func addBarButtonItems(types: [REWEBarButtonItemType]) {
    // actual implementation
}

Я знаю, что этот ответ не ответ на ваш точный вопрос, но я чувствую, что его стоит отметить. Я тоже начал играть со Свифтом и сразу же столкнулся с подобным вопросом. Manojlds ответ лучше для вашего вопроса, я согласен, но опять же, еще один обходной путь я придумал. Мне тоже больше нравится Логан.

в моем случае я просто хотел передать массив:

func sumOf(numbers: Array<Int>) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}

var someNums = [8,7,2,9,12]
sumOf(someNums)
sumOf([10, 15, 20])

просто хотел поделиться, в случае, если кто-то еще думал, как я. Большую часть времени я бы предпочитаю передать массив таким образом, но я не думаю, что "быстро" еще. :)