Passing an array to a function with variable number of args in Swift

喜夏-厌秋 提交于 2019-11-26 00:54:17

问题


In The Swift Programming Language, it says:

Functions can also take a variable number of arguments, collecting them into an array.

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

When I call such a function with a comma-separated list of numbers (`sumOf(1, 2, 3, 4), they are made available as an array inside the function.

Question: what if I already have an array of numbers that I want to pass to this function?

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

This fails with a compiler error, “Could not find an overload for \'__conversion\' that accepts the supplied arguments”. Is there a way to turn an existing array into a list of elements that I can pass to a variadic function?


回答1:


Splatting is not in the language yet, as confirmed by the devs. Workaround for now is to use an overload or wait if you cannot add overloads.




回答2:


Here's a work around that I found. I know it's not exactly what you want, but it seems to be working.

Step 1: Declare the function you'd like with an array instead of variadic arguments:

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

Step 2: Call this from within your variadic function:

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

Step 3: Call Either Way:

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

It seems strange, but it is working in my tests. Let me know if this causes unforeseen problems for anyone. Swift seems to be able to separate the difference between the two calls with the same function name.

Also, with this method if Apple updates the language as @manojid's answer suggests, you'll only need to update these functions. Otherwise, you'll have to go through and do a lot of renaming.




回答3:


You can cast the function:

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



回答4:


You can use a helper function as such:

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



回答5:


I know this response does not answer your exact question, but I feel its worth noting. I too was starting to play with Swift and immediately ran into a similar question. Manojlds answer is better for your question, I agree, but again, another workaround I came up with. I do happen to like Logan's better too.

In my case I just wanted to pass an array:

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])

Just wanted to share, in case anyone else was thinking like me. Most of the time I would prefer pass the array like this, but I don't think the "Swiftly" yet. :)




回答6:


I did this (Wrapper + Identity Mapping):

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

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


来源:https://stackoverflow.com/questions/24024376/passing-an-array-to-a-function-with-variable-number-of-args-in-swift

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