Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.


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.


You can cast the function:

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

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

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. :)